当前位置:首页 > 技术知识 > 正文内容

嵌入式编程模型 | 简单工厂模式_嵌入式程序编程

maynowei7个月前 (09-29)技术知识80

一、简单工厂模式

简单工厂模式(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驱动

相关文章

如何快速将axure生成的原型放到手机上演示

人人都是产品经理旗下【起点学院】推出产品经理“365天”成长计划,BAT大牛带你学产品! 之前Axure官方有一个原型在线分享演示的平台,用户可以直接生成原型到Axure官方平台,方便用户提供演示:h...

单片机C语言编程,心得都在这里了

单片机写代码总踩坑,头文件被无视,老工程师的经验哪里来?前几天写8x8矩阵键盘的程序,搞了三天代码一直乱报错。后来发现自己连头文件是什么都不清楚,之前写的都是小程序,压根没碰过.h文件。看别人的程序都...

微软宣布SQL Server 2016,2005版将结束支持

IT之家讯 在芝加哥Ignite大会上,微软宣布了SQL Server 2016,并将于今年夏季发布公开预览版。SQL Server是由微软开发的关系型数据库管理系统,用于软件应用请求数据的存储和管理...

Shopee新手指南:Shopee卖家中心用户界面介绍

1.Shopee各站点前台网页链接:2.Shopee各站点后台网页链接3.Shopee APP下载:安卓版下载链接:https://pan.baidu.com/s/1eSp8M1k#list/path...

从 async/await 到虚拟线程:Python 并发的再思考

演进之路:从async/await到线程的反思首先必须明确的是,async/await对Python并非全无裨益:它最大的价值,是让更多人接触到了并发编程。通过在编程语言中嵌入语法元素,并发编程的门槛...

聊聊并发编程: Lock(并发锁有哪些)

之前学习了如何使用synchronized关键字来实现同步访问,Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功...