一、简单工厂模式
简单工厂模式(Simple Factory Pattern)又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
通过一个工厂类封装对象的创建逻辑,根据输入参数动态实例化具体产品类,实现创建与使用的解耦。
在嵌入式系统中,该模式尤其适用于:
- 多硬件驱动兼容
- 资源受限场景
- 跨平台适配
简单工程模式核心结构包含如下部分:
- 工厂类:负责实现创建所有实例的内部逻辑。
- 抽象产品接口:所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
- 具体产品类:所有创建的对象都充当这个角色的某个具体类的实例。
二、嵌入式应用案例
1、LCD工厂框图
- 工厂类:根据传入的型号参数创建对应的LCD驱动实例。
- 抽象产品接口:LCD驱动接口(包含初始化、写命令、写数据等方法)。
- 具体产品类:不同型号的LCD驱动(例如ST7789Driver, ILI9341Driver)。
2、代码实现
UML类图:
嵌入式设备需支持多种LCD屏幕(如ST7789、ILI9341),其初始化、写命令等底层驱动差异大,但上层应用需统一调用接口。
代码实现:
C语言:
typedef enum{
LCD_ST7789,
LCD_ILI9341
} LCD_Type;
// 抽象产品:LCD操作接口
typedef struct {
void (*Init)(void);
void (*WriteCommand)(uint8_t cmd);
void (*DisplayText)(const char *text);
void (*Clear)(void);
} LCD_Driver;
// 具体产品:ST7789驱动
void ST7789_Init(void){}
void ST7789_WriteCommand(uint8_t cmd){}
void ST7789_DisplayText(const char *text){}
void ST7789_Clear(void){}
LCD_Driver ST7789_Driver = {
ST7789_Init,
ST7789_WriteCommand,
ST7789_DisplayText,
ST7789_Clear,
};
// 具体产品:ILI9341驱动
void ILI9341_Init(void){}
void ILI9341_WriteCommand(uint8_t cmd){}
void ILI9341_DisplayText(const char *text){}
void ILI9341_Clear(void){}
LCD_Driver ILI9341_Driver = {
ILI9341_Init,
ILI9341_WriteCommand,
ILI9341_DisplayText,
ILI9341_Clear,
};
// 工厂类:根据屏幕类型返回驱动实例(此处屏蔽不用)
//typedef struct {
// void (*Create)(LCD_Type type);
//} LCD_Factory;
LCD_Driver* LCD_Factory_Create(LCD_Type type) {
switch (type) {
case LCD_ST7789: return &ST7789_Driver;
case LCD_ILI9341: return &ILI9341_Driver;
default: return NULL;
}
}
C++:
// 抽象产品类:LCD操作接口
class LCD_Driver {
public:
virtual void Init() = 0;
virtual void WriteCommand(uint8_t cmd) = 0;
virtual void DisplayText(const char *text) = 0;
virtual void Clear() = 0;
virtual ~LCD_Driver() {}
};
// 具体产品类:ST7789驱动
class ST7789_Driver : public LCD_Driver {
public:
void Init() override;
void WriteCommand(uint8_t cmd) override;
void DisplayText(const char *text) override;
void Clear() override;
};
void ST7789_Driver::Init() {}
void ST7789_Driver::WriteCommand(uint8_t cmd) {}
void ST7789_Driver::DisplayText(const char *text) {}
void ST7789_Driver::Clear() {}
// 具体产品类:ILI9341驱动
class ILI9341_Driver : public LCD_Driver {
public:
void Init() override;
void WriteCommand(uint8_t cmd) override;
void DisplayText(const char *text) override;
void Clear() override;
};
void ILI9341_Driver::Init() {}
void ILI9341_Driver::WriteCommand(uint8_t cmd) {}
void ILI9341_Driver::DisplayText(const char *text) {}
void ILI9341_Driver::Clear() {}
// 工厂类
class LCD_Factory {
public:
enum LCD_Type { LCD_ST7789, LCD_ILI9341 };
// 创建LCD驱动实例
static LCD_Driver* Create(LCD_Type type) {
switch (type) {
case LCD_ST7789:
return new ST7789_Driver();
case LCD_ILI9341:
return new ILI9341_Driver();
default:
return nullptr;
}
}
};
调用示例:
LCD_Driver *lcd = LCD_Factory_Create(LCD_ST7789);
lcd->Init();
3、优缺点
优点:
(1)更换LCD只需改一行代码:
// 从ST7789切换到ILI9341
LCD_Driver *lcd = LCD_Factory_Create(LCD_ILI9341);
(2)统一操作接口:
// 无论什么型号的LCD,调用方式相同
lcd->DisplayText("Temp: 25.5C");
lcd->Clear();
(3)方便扩展新LCD型号:
// 具体产品:xxx驱动
void xxx_Init(void){}
void xxx_WriteCommand(uint8_t cmd){}
void xxx_DisplayText(const char *text){}
void xxx_Clear(void){}
LCD_Driver xxx_Driver = {
xxx_Init,
xxx_WriteCommand,
xxx_DisplayText,
xxx_Clear,
};
缺点:
(1)违反开闭原则:新增驱动需修改工厂
LCD_Driver* LCD_Factory_Create(uint8_t type) {
switch (type) {
case LCD_ST7789: return &ST7789_Driver;
case LCD_ILI9341: return &ILI9341_Driver;
// 新增驱动必须修改此处 ↓
case LCD_XXX: return &XXX_Driver;
default: return NULL;
}
}
每次新增LCD型号都需要修改工厂函数,违反"对扩展开放,对修改关闭"原则。在固件升级时可能引入风险。
(2)工厂职责过重:集中所有创建逻辑
LCD_Driver* LCD_Factory_Create(uint8_t type) {
switch (type) {
case LCD_ST7789: return &ST7789_Driver;
case LCD_ILI9341: return &ILI9341_Driver;
// 可能还有数十种驱动
default: return NULL;
}
}
当支持10+种LCD时,函数变得臃肿;编译后代码体积增大。
三、嵌入式场景适用性总结
简单工厂模式的要点在于:当我们需要什么,只需要向工厂传入一个正确的参数,就可以获取我们所需要的产品实例,而无须知道其创建细节。
场景 | 优势 | 案例 |
多硬件驱动兼容 | 统一接口,降低耦合 | LCD/传感器驱动管理 |
动态算法选择 | 按需加载轻量化模块 | 图像识别算法切换 |
跨平台运行时适配 | 封装OS/芯片相关代码 | RTOS vs Linux驱动 |