当前位置: 首页 > news >正文

设计模式学习(二)工厂模式——抽象工厂模式+注册表

设计模式学习(二)工厂模式——抽象工厂模式+注册表

  • 前言
  • 使用简单工厂改进
  • 使用注册表改进
  • 参考文章

前言

在上一篇文章中我们提到了抽象工厂模式初版代码的一些缺点:①客户端违反开闭原则②提供方违反开闭原则。本文将针对这两点进行讨论

使用简单工厂改进

对于缺点①,我们可以使用简单工厂的思路来改进抽象工厂的初版代码。对于上一篇文章中的例子,我们去除CameraFactoryBaslerCameraFactorySickCameraFactory,取而代之的是SimpleFactory类。

类图如下:
在这里插入图片描述
代码如下:

//工厂类
class SimpleFactory
{
public:BaslerCamera* CreateBaslerCamera(){if ("Linux" == os_name_){return new LinuxBaslerCamera();}else if ("Windows" == os_name_){return new WindowsBaslerCamera();}else{return nullptr;}}SickCamera* CreateSickCamera(){if ("Linux" == os_name_){return new LinuxSickCamera();}else if ("Windows" == os_name_){return new WindowsSickCamera();}else{return nullptr;}}
public:std::string os_name_ = "Linux";};//客户端
int main()
{SimpleFactory* camera_factory = new SimpleFactory();BaslerCamera* basler_camera = camera_factory->CreateBaslerCamera();basler_camera->OpenCamera();SickCamera* sick_camera = camera_factory->CreateSickCamera();sick_camera->OpenCamera();return 0;
}

注意,上述方法虽然改进了缺点①,但是缺点②仍存在。

使用注册表改进

对于缺点②,其本质是:增加新产品时,对工厂类带来的修改违反了开闭原则。对于这种情况,我们可以参考《设计模式学习(二)工厂模式——工厂方法模式+注册表》中提到的注册表,来去除switchif这种分支判断,解除分支判断带来的耦合。

对于具体产品,我们可以这样将它注册:

class LinuxBaslerCamera : public BaslerCamera
{
public:~LinuxBaslerCamera() override = default;bool OpenCamera() override{return true;}
};ReflectRegister("LinuxBasler", LinuxBaslerCamera);

然后工厂类的代码可以简化为:

class SimpleFactory
{
public:BaslerCamera* CreateBaslerCamera(){std::string name = os_name_ + "Basler";return Object::CreateObject<BaslerCamera>(name);}SickCamera* CreateSickCamera(){std::string name = os_name_ + "Sick";return Object::CreateObject<SickCamera>(name);}
public:std::string os_name_ = "Linux";
};

这样,在产品族增加时(比如增加一个HarmonyOS),我们只需要在它下面的产品类对应的文件中使用ReflectRegister注册,然后改变os_name_即可(当然os_name_也可以在运行时从配置文件中加载,这样更好)。

而对于现有的产品族内增加新产品(比如增加一个Huaray相机),工厂类中还是要增加一个CreateHuarayCamera函数。

参考文章

1.《大话设计模式》

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Token Labeling(NeurIPS 2021, ByteDance)论文解读
  • 数据结构--二叉树遍历
  • SAP 消息输出 - Adobe Form
  • C++相关概念和易错语法(22)(final、纯虚函数、继承多态难点)
  • Odoo创建一个自定义UI视图
  • sentinel网关限流配置及使用
  • 一篇就够mysql高阶知识总结
  • UDP-如何实现客户端与服务器端的通信(一对一、一对多、多对一、多对多之间的通信)
  • C语言丢失精度 如何实现高精度计算
  • ThreadLocal源码分析
  • Spring-Boot基础--yaml
  • Qcom平台通过Hexagon IDE 测试程序性能指导
  • Puppeteer动态代理实战:提升数据抓取效率
  • Qt: 窗口停靠框架
  • PostgreSQL创建表和自增序列
  • bootstrap创建登录注册页面
  • canvas绘制圆角头像
  •  D - 粉碎叛乱F - 其他起义
  • Electron入门介绍
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • EventListener原理
  • Java 内存分配及垃圾回收机制初探
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript函数式编程(一)
  • js数组之filter
  • Linux各目录及每个目录的详细介绍
  • Logstash 参考指南(目录)
  • uva 10370 Above Average
  • 对超线程几个不同角度的解释
  • 记一次和乔布斯合作最难忘的经历
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 深入浅出webpack学习(1)--核心概念
  • 微信小程序--------语音识别(前端自己也能玩)
  • 《码出高效》学习笔记与书中错误记录
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 如何用纯 CSS 创作一个货车 loader
  • ​Spring Boot 分片上传文件
  • #微信小程序(布局、渲染层基础知识)
  • $forceUpdate()函数
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (4) PIVOT 和 UPIVOT 的使用
  • (55)MOS管专题--->(10)MOS管的封装
  • (笔记)M1使用hombrew安装qemu
  • (纯JS)图片裁剪
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • **PHP分步表单提交思路(分页表单提交)
  • .libPaths()设置包加载目录
  • .net core Redis 使用有序集合实现延迟队列
  • .NET Core 成都线下面基会拉开序幕