C++ Arduino触摸屏项目工厂模式创建Screen实例实现咨询
选型判断
你选单工厂+枚举匹配的方案完全合理,不需要硬套抽象工厂+多子类的结构,尤其你是在Arduino这种资源极度受限的嵌入式环境下做开发,过度设计反而会带来额外负担。
为什么不推荐硬套标准抽象工厂实现
- 抽象工厂/工厂方法模式的核心适用场景是跨产品族的创建逻辑解耦:比如你做一套通用UI框架,需要给Windows、Mac、嵌入式三个平台各提供一套控件实现,同一套调用逻辑要能切换不同平台的工厂类生成对应控件,这种场景下拆工厂父类和多子类才有意义。你的项目里所有Screen都是服务于当前固定硬件的,不存在跨产品族、动态替换工厂实现的需求,拆一堆工厂子类只会平白增加代码体积,浪费Flash和RAM。
- 你的所有可展示Screen是固定、可枚举的,没有给第三方留扩展入口的需求,单工厂的实现维护成本最低,代码可读性最高,完全符合嵌入式开发常用的KISS(保持简单直接)原则。
适配Arduino场景的简单工厂实现参考
针对MCU内存小、容易出堆碎片的特点,实现的时候尽量减少动态内存分配,参考代码如下:
// 先定义所有Screen类型的枚举,用uint8_t做底层类型减少内存占用 enum class ScreenType : uint8_t { MAIN_MENU, SETTINGS, SENSOR_VIEW, WARNING_POPUP }; // 前置声明你实现的各个Screen子类 class MainMenuScreen; class SettingsScreen; class SensorViewScreen; class WarningPopupScreen; class ScreenFactory { public: // 全局用同一个工厂实例,避免重复创建浪费内存 static ScreenFactory& instance() { static ScreenFactory fac; return fac; } // 传入枚举返回对应Screen实例指针 Screen* getScreen(ScreenType type) { switch (type) { // 常驻页面用静态实例,不反复创建销毁,从根源避免内存碎片 case ScreenType::MAIN_MENU: { static MainMenuScreen mainMenu; return &mainMenu; } case ScreenType::SETTINGS: { static SettingsScreen settings; return &settings; } case ScreenType::SENSOR_VIEW: { static SensorViewScreen sensorView; return &sensorView; } // 弹窗类需要每次重置状态的页面,再用动态分配,不用时记得手动释放 case ScreenType::WARNING_POPUP: { return new WarningPopupScreen(); } default: return nullptr; } } private: // 私有化构造/析构/拷贝,禁止外部随意创建工厂实例 ScreenFactory() = default; ~ScreenFactory() = default; ScreenFactory(const ScreenFactory&) = delete; ScreenFactory& operator=(const ScreenFactory&) = delete; }; // 调用示例 /* void loop() { if (touchPressedSettingBtn()) { Display::getInstance().switchScreen(ScreenFactory::instance().getScreen(ScreenType::SETTINGS)); } } */
实现注意事项
- 不要为了凑设计模式的“标准实现”强行加不需要的结构:设计模式是解决重复问题的经验模板,不是必须严格遵守的开发规范,只要能满足需求、易维护、适配运行环境就是好的实现。
- 后续新增Screen时,只需要在枚举里加对应类型,在switch分支里加对应返回逻辑即可,不需要修改其他代码,扩展成本极低。
- 如果你的项目后续真的出现了需要适配不同屏幕驱动、不同硬件版本生成不同Screen组的需求,再重构为抽象工厂结构也完全来得及,前期没必要提前做过度设计。
内容的提问来源于stack exchange,提问作者asloan2410
相关产品推荐
相关产品推荐

