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

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

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

前言

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

使用简单工厂改进

对于缺点①,我们可以使用简单工厂的思路来改进抽象工厂的初版代码。对于上一篇文章中的例子,我们去除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.《大话设计模式》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/378299.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【node-RED 4.0.2】连接 Oracle 数据库踩坑解决,使用模组:node-red-contrib-agur-connector

关于 Oracle Oracle 就好像一张吸满水的面巾纸&#xff0c;你稍一用力它就烂了。 PS&#xff1a;我更新了更好的模组的教程&#xff0c;这篇已经是旧款的教程&#xff0c;但是它仍旧包含了必要的配置环境变量等操作。 最新的模组教程&#xff1a;node-red-contrib-agur-connec…

数据湖仓一体(一) 编译hudi

目录 一、大数据组件版本信息 二、数据湖仓架构 三、数据湖仓组件部署规划 四、编译hudi 一、大数据组件版本信息 hudi-0.14.1zookeeper-3.5.7seatunnel-2.3.4kafka_2.12-3.5.2hadoop-3.3.5mysql-5.7.28apache-hive-3.1.3spark-3.3.1flink-1.17.2apache-dolphinscheduler-3.1.9…

基于AT89C51单片机的16×16点阵LED显示器字符滚动显示设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于AT89C51单片机的1616点阵LED显示器字符滚动显示设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 仿真效果图 仿真图 代码 系统论文 资源下载 设计的内容和要求 熟悉51系…

基于视觉工具箱和背景差法的行人检测,行走轨迹跟踪,人员行走习惯统计matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 在三维图中&#xff0c;幅度越大&#xff0c;则表示人员更习惯的行走路线。 2.算法运行软件版本 matlab2022a 3.部分核…

css基础(1)

CSS CCS Syntax CSS 规则由选择器和声明块组成。 CSS选择器 CSS选择器用于查找想要设置样式的HTML元素 一般选择器分为五类 Simple selectors (select elements based on name, id, class) 简单选择器&#xff08;根据名称、id、类选择元素&#xff09; //页面上的所有 …

【经验分享】关于静态分析工具排查 Bug 的方法

文章目录 编译器的静态分析cppcheck安装 cppcheck运行 cppcheck 程序员的日常工作&#xff0c;不是摸鱼扯皮&#xff0c;就是在写 Bug。虽然这是一个梗&#xff0c;但也可以看出&#xff0c;程序员的日常一定绕不开 Bug。而花更少的时间修复软件中的 Bug&#xff0c;且不引入新…

Bug:时间字段显示有问题

Bug&#xff1a;时间字段显示有问题 文章目录 Bug&#xff1a;时间字段显示有问题1、问题2、解决方法一&#xff1a;添加注解3、解决方法二&#xff1a;消息转换器自定义对象映射器配置消息转换器 1、问题 ​ 在后端传输时间给前端的时候&#xff0c;发现前端的时间显示有问题…

汽车开发阶段(OTS/VFF/PVS/OS/SOP)

OTS&#xff1a;即英语中的Off Tooling Sample&#xff0c;通常被称为工装样件。它指的是通过配套设备、工装夹具以及模具制造出来的样品&#xff0c;但并不强调生产的时间效率&#xff0c;主要用于验证产品的设计能力。 VFF&#xff1a;在德语中表示为Vorserien Freigabefahr…

太速科技-FMC207-基于FMC 两路QSFP+光纤收发子卡

FMC207-基于FMC 两路QSFP光纤收发子卡 一、板卡概述 本卡是一个FPGA夹层卡&#xff08;FMC&#xff09;模块&#xff0c;可提供高达2个QSFP / QSFP 模块接口&#xff0c;直接插入千兆位级收发器&#xff08;MGT&#xff09;的赛灵思FPGA。支持利用Spartan-6、Virtex-6、Kin…

eNsp公司管理的网络NAT策略搭建

实验拓扑图 实验需求&#xff1a; 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带…

JavaWeb(四:Ajax与Json)

一、Ajax 1.定义 Ajax&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff1a;异步的 JavaScript 和 XML AJAX 不是新的编程语言&#xff0c;指的是⼀种交互方式&#xff1a;异步加载。 客户端和服务器的数据交互更新在局部页面的技术&#xff0c;不需要刷新…

VUE:跨域配置代理服务器

//在vite.config。js中&#xff0c;同插件配置同级进行配置server:{proxy:{"/myrequest":{//代理域名&#xff0c;可自行修改target:"https://m.wzj.com/",//访问服务器的目标域名changeOrigin:true,//允许跨域configure:(proxy,options) > {proxy.on(&…

未知物材料成分配方检测分析

材料成分配方分析是一种通过分析材料的化学成分、结构和性质来确定其组成和配方的方法。这对于产品质量控制、新产品研发、工业问题解决和环保等领域具有重要意义。进行材料成分配方分析通常需要以下步骤&#xff1a; 1. 样品采集&#xff1a;采集需要分析的材料样品&#xff0…

从 Pandas 到 Polars 十八:数据科学 2025,对未来几年内数据科学领域发展的预测或展望

我在2021年底开始使用Polars和DuckDB。我立刻意识到这些库很快就会成为数据科学生态系统的核心。自那时起&#xff0c;这些库的受欢迎程度呈指数级增长。 在这篇文章中&#xff0c;我做出了一些关于未来几年数据科学领域的发展方向和原因的预测。 这篇文章旨在检验我的预测能力…

再谈有关JVM中的四种引用

1.强引用 强引用就是我们平时使用最多的那种引用&#xff0c;就比如以下的代码 //创建一个对象 Object obj new Object();//强引用 这个例子就是创建了一个对象并建立了强引用&#xff0c;强引用一般就是默认支持的当内存不足的时候&#xff0c;JVM开始垃圾回收&#xff0c…

【Linux系统编程】软硬链接和动静态库

一&#xff0c;硬链接 1-1&#xff0c;硬链接的认识 Linux下的硬链接本质是在指定的目录下&#xff0c;插入新的文件名和目标文件的眏射关系&#xff0c;并让inode的引用计数加一&#xff0c;这里我们通过 ls 指令可查看到文件详细信息种的硬链接数。这里可参考文件系统的文章…

Linux - 冯-诺依曼体系结构、初始操作系统

目录 冯•诺依曼体系 结构推导 内存提高效率的方法 数据的流动过程 体系结构相关知识 初始操作系统 定位 设计目的 操作系统之上之下分别有什么 管理精髓&#xff1a;先描述&#xff0c;再组织 冯•诺依曼体系 结构推导 计算机基本工作流程图大致如下&#xff1a; 输入设备&a…

Web3D:WebGL为什么在渲染性能上输给了WebGPU。

WebGL已经成为了web3D的标配&#xff0c;市面上有N多基于webGL的3D引擎&#xff0c;WebGPU作为挑战者&#xff0c;在渲染性能上确实改过webGL一头&#xff0c;由于起步较晚&#xff0c;想通过这个优势加持&#xff0c;赶上并超越webGL仍需时日。 贝格前端工场为大家分享一下这…

【微信小程序知识点】自定义构建npm

在实际开发中&#xff0c;随着项目的功能越来越多&#xff0c;项目越来越复杂&#xff0c;文件目录也变得很繁琐&#xff0c;为了方便进行项目的开发&#xff0c;开发人员通常会对目录结构进行优化调整&#xff0c;例如&#xff1a;将小程序源码放到miniprogram目录下。 &…

JuiceFS缓存特性

缓存 对于一个由对象存储和数据库组合驱动的文件系统&#xff0c;缓存是本地客户端与远端服务之间高效交互的重要纽带。读写的数据可以提前或者异步载入缓存&#xff0c;再由客户端在后台与远端服务交互执行异步上传或预取数据。相比直接与远端服务交互&#xff0c;采用缓存技…