简单工厂模式 创建型模式(非GoF经典设计模式)
简单工厂模式是属于创建型模式,也因为工厂中的方法一般设置为静态,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
1.示例代码解读
//简单工厂模式工厂代码
#include <iostream>
using namespace std;//抽象产品
class AbstractProduct
{
public:virtual ~AbstractProduct() {}virtual void Operation() = 0;
};class SimpleFactory
{
public:static AbstractProduct* CreateProduct(const std::string& type);
};int main()
{AbstractProduct* productA = SimpleFactory::CreateProduct("A");productA->Operation();AbstractProduct* productB = SimpleFactory::CreateProduct("B");productB->Operation();delete productA;delete productB;return 0;
}
1.1 核心函数
设计模式只是我们总结的一种方法论,我想强调的是,设计模式仅仅是我们做事情的方法或者说是套路,而我们应用它的目的是为了解决我们的问题本身。先不要觉得的思路有点儿莫名其妙,我先请大家回答一个问题,在上述的代码里,真正的核心是哪一个函数?或者说与业务最相关的是哪个函数? 没错,是Operation(),就是这个函数。
我们搞了那么多套路,那么多设计模式,无非就是为了调用Operation()函数,完成我们想要完成的工作不是么?比如Opertion()函数是用来读某一种格式的文件的。但是我再问大家一个问题,你在使用这个函数的时候,你需要关心它具体是怎么做的么?比如它读一个txt,你会关心它具体怎么去解析这个问题的内容么?往往不会对么,除非你是负责做文件解析的,但是在使用这段代码的时候,当时的角色一定不是为了做文件解析本身,而是想要拿到文件解析的成果。而事实上,大多数情况下,你根本是拿不到Operation()实现的具体代码细节。就比如上述的代码,你只看到了这个函数接口,而拿不到函数实现。
1.2 迪米特法则
大家发现没有,我们最关心的Operation(),我们既不知道它具体是怎么实现的(但是我们当然得知道它用来做什么,这个一般会写上接口说明,如果你连这个函数的作用都不知道,你还用个der)。事实上,我们连具体是什么类型的对象的函数也不知道(我们只知道它的抽象类)。看到没,这样一种封装是不是做的很漂亮很极致,不该知道的你都不知道,都被完美的封装起来了。这就是迪米特法则,又称最少知道原则(Demeter Principle)。也就是说,你只需要知道你需要选择创建什么样的类型的“产品”,来执行你的操作就好了。还是用解析文件的例子,比如你需要解析的文件是txt格式的,那你就选择解析txt格式的“产品”,如果你需要解析“jpg”格式的产品你就设置对应的类型即可。创建完对应的类型,直接调用Operation()函数,即可完成工作,是不是非常的无脑简单。
1.3 扩展问题
这个时候聪明的同学就会问了,如果我想解析一种新的文件格式咋整。好,那就要涉及到需要增加新“产品”的问题了。这个时候你就需要请做这个工厂模式文件解析库的同学来帮忙了。我们来看看他在扩展这个需求的时候需要做什么工作。这里我们需要把全部的核心的简单工厂模式代码打开来看。
//简单工厂模式工厂代码
#include <iostream>
using namespace std;//抽象产品
class AbstractProduct
{
public:virtual ~AbstractProduct() {}virtual void Operation() = 0;
};class SimpleFactory
{
public:static AbstractProduct* CreateProduct(const std::string& type);
};int main()
{AbstractProduct* productA = SimpleFactory::CreateProduct("A");productA->Operation();AbstractProduct* productB = SimpleFactory::CreateProduct("B");productB->Operation();delete productA;delete productB;return 0;
}//具体产品
class ProductA : public AbstractProduct
{
public:void Operation() {cout << "ProductA" << endl;}
};//具体产品B
class ProductB : public AbstractProduct {
public:void Operation() {cout << "ProductB" << endl;}
};AbstractProduct* SimpleFactory::CreateProduct(const std::string& type){if (type == "A")return new ProductA();else if (type == "B")return new ProductB();elsereturn nullptr;}
这里我偷了个懒,没有把声明和实现分开放在.h和.cpp文件里,大家知道就行。大家可以看到,main函数之下的代码就是具体的实现代码了。我们在第一份代码里,看到有A,B两个产品。现在我们需要增加C产品。我们要改两个地方:
- 需要再派生一个具体的产品类C,且实现Opertion()函数的具体功能。
- 工厂的CreateProduc函数需要做新增的判断。
最后我们的这个简单工厂模块需要重新编译(一般都是以链接库的方式提供给其他人调用)。到此位置我们代码解读部分就完成了。
2.组成结构
简单工厂模式包含以下几个主要组成部分:
- Factory(简单工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象。
- Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象。
- ConcreteProduct(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法(有关抽象类)。
3.工作流程
简单工厂模式的工作流程如下:
- 客户端通过调用工厂类的方法来请求一个产品对象。
- 工厂类根据客户端的请求,决定实例化哪个具体产品对象。
- 工厂类实例化具体产品对象,并将其返回给客户端。
- 客户端通过产品接口操作具体产品对象。
3.优缺点
2.1 优点
- 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
总结:只需要传入一个正确的参数,就可以获取你所需要的对象而无需知道其创建对象的细节
2.2 缺点
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
总结:扩展性差,当增加新的产品需要修改工厂类的判断逻辑,违背开闭原则,如我想要买一个华为手机的话,除了新增华为手机这个产品类,还需要修改工厂中的逻辑
4.应用场景
- 创建型模式:简单工厂模式是一种创建型模式,它的主要目的是为了实现解耦,将对象的创建和使用分开,即应用程序将对象的创建和初始化职责交给工厂对象。通过简单工厂,实现了调用类和具体实现类的解耦,使用者不需要知道具体的创建过程,只需要使用即可。
- 封装具体实现:如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装类,那么可以选择简单工厂模式。通过简单工厂,可以将对外创建对象的职责集中管理和控制。
- 降低代码重复:如果对象B的创建过程比较复杂,并且很多地方都用到了,那么很可能出现很多重复的代码。通过统一将创建对象B的代码放到工厂里面统一管理,可以减少代码的重复率,同时也方便维护。
- 处理子类:当类本身有很多子类,并且经常性发生变化时,可以使用简单工厂模式。
5.引用
设计模式简单学——简单工厂模式 (baidu.com)
相关文章:
简单工厂模式 创建型模式(非GoF经典设计模式)
简单工厂模式是属于创建型模式,也因为工厂中的方法一般设置为静态,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工…...
PE文件之导入表
1. 导入表 2. 显示导入表信息的例子 ; 作用: 将RVA地址转成FOA即文件偏移 ; 参数: _pFileHdr 指向读到内存中文件的基址指针 ; _dwRVA 目标RVA地址 ; 返回: 目标RVA转成文件偏移的值 RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORDmov esi, _pFil…...
二、码制及其转换
原码 根据我们所学可知,数字电路的逻辑电路是通过输出0和1来表示二进制数的,那么这个二进制数的正负又该怎么表示呢? 答案是在这个二进制数的最高位作为符号位来表示正负性,用0正数,用1表示负数,在这种表达…...
在pycharm中出现下载软件包失败的解决方法
一. 一般情况下我们会选择在设置中下载软件包,过程如下. 1. 直接点击左上角的文件, 再点击设置, 再点击项目, 在右边选择python解释器,点击号,输入要下载的软件包, 在下面的一系列的包中选择相对应的包,点击安装就可以了,有的时候我们下载的是最新的版本,如果要下载固定的版本…...
10.0 探索API调试事件原理
本章笔者将通过Windows平台下自带的调试API接口实现对特定进程的动态转存功能,首先简单介绍一下关于调试事件的相关信息,调试事件的建立需要依赖于DEBUG_EVENT这个特有的数据结构,该结构用于向调试器报告调试事件。当一个程序发生异常事件或者…...
文心一言 VS 讯飞星火 VS chatgpt (104)-- 算法导论10.1 2题
二、用go语言,说明如何在一个数组 A[1…n]中实现两个栈,使得当两个栈的元素个数之和不为 n 时,两者都不会发生上溢。要求 PUSH 和 POP 操作的运行时间为 O(1)。 文心一言: 在这个问题中,我们要在一个数组 A[1…n] 中…...
检测防火墙是否开启、判断程序是否加入防火墙白名单(附源码)
VC常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...&a…...
vtk 动画入门 1 代码
实现效果如图: #include <vtkAutoInit.h> //VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //VTK_MODULE_INIT(vtkRenderingFreeType); #in…...
【VR】【unity】如何在VR中实现远程投屏功能?
【背景】 目前主流的VD应用,用于娱乐很棒,但是用于工作还是无法效率地操作键鼠。用虚拟键盘工作则显然是不现实的。为了让自己的头显能够起到小面积代替多显示屏的作用,自己动手开发投屏VR应用。 【思路】 先实现C#的投屏应用。研究如何将C#投屏应用用Unity 3D项目转写。…...
OpenGl材质
在现实世界里,每个物体会对光产生不同的反应。比如,钢制物体看起来通常会比陶土花瓶更闪闪发光,一个木头箱子也不会与一个钢制箱子反射同样程度的光。有些物体反射光的时候不会有太多的散射(Scatter),因而产生较小的高光点,而有些物体则会散射很多,产生一个有着更大半径的…...
背包问题
目录 开端 01背包问题 AcWing 01背包问题 Luogu P2925干草出售 Luogu P1048采药 完全背包问题 AcWing 完全背包问题 Luogu P1853投资的最大效益 多重背包问题 AcWing 多重背包问题 I AcWing 多重背包问题 II Luogu P1776宝物筛选 混合背包问题 AcWing 混合背包问题…...
JavaSE | 初始Java(十一) | 抽象类和抽象接口
抽象类概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的, 如果 一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类 在 Java 中,一个…...
产品经理如何科学的进行需求调研?
导语:作为产品经理,需求调研是开展工作的重要环节之一。科学、有效地进行需求调研不仅可以帮助产品经理更好地了解用户需求,还能指导产品设计和功能开发,提升产品的竞争力。本文将介绍几种科学的方法和技巧,帮助产品经…...
AI智能问答系统源码/AI绘画商业系统/支持GPT联网提问/支持Midjourney绘画
一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图…...
玩具玩偶配送经营商城小程序的作用是什么?
玩具玩偶是小孩子们喜欢的产品,其市场需求度很高,以前玩具店里总是不缺乏客户,但现在随着人们生活品牌提升及消费形式改变,无论玩具厂商还是门店经销商都面对着不少痛点: 如拓客引流难、线上销售经营难、营销难、分销…...
latex表格内容换行
问题描述: 在用latex表格中编写公式时,可能出现公式太长,表格中后面的内容不能在文档中呈现,如下图1,故要进行行内内容的换行,使内容呈现完全而传统的\换行后,换行内容会顶格,如图2。 解决方…...
2023 牛客国庆day4 【10.2训练补题】
目录 B-Basic Gcd Problem(素数筛快速幂) H-Harder Gcd Problem(素数) B-Basic Gcd Problem(素数筛快速幂) 打表找规律发现答案为 (n质因子数目)^c #include<bits/stdc.h> using namespace std;…...
android的USB开发时 mUsbManager.getDeviceList()获取都为空
类提供的主要方法有: getDeviceList() 获得设备列表,返回的是一个HashMap.;hasPermission(UsbDevice device) 判断你的应用程序是否有接入此USB设备的权限,如果有则返回真,否则返回false.openDevice(UsbDevice device) 打开USB设…...
SpringCloud Alibaba - Seata 部署 TC 服务,并集成微服务
目录 一、Seata 架构 1.1、Seata 架构重要角色 1.2、部署 TC 服务 1.2.1、前言 1.2.2、下载 seata-server 包,解压 1.2.3、修改配置 1.2.4、在 nacos 中添加配置 1.2.5、创建数据库表 1.2.6、启动 TC 服务 1.3、微服务集成 Seata 1.3.1、引入依赖 1.3.2、…...
Java基础面试,接口和抽象类的区别?
接口和抽象类的区别? 抽象类可以存在普通成员函数,而接口中只能存在public abstract 方法。抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的.抽象类只能继承一个,接口可以实现多个。 接…...
《视觉 SLAM 十四讲》V2 第 4 讲 李群与李代数 【什么样的相机位姿 最符合 当前观测数据】
P71 文章目录 4.1 李群与李代数基础4.1.3 李代数的定义4.1.4 李代数 so(3)4.1.5 李代数 se(3) 4.2 指数与对数映射4.2.1 SO(3)上的指数映射罗德里格斯公式推导 4.2.2 SE(3) 上的指数映射SO(3),SE(3),so(3),se(3)的对应关系 4.3 李代数求导与扰动模型4.3.2 SO(3)上的李代数求导…...
【深蓝学院】手写VIO第4章--基于滑动窗口算法的 VIO 系统:可观性和 一致性--笔记
0. 内容 T1. 参考SLAM14讲P247直接可写,注意 ξ 1 , ξ 2 \xi_1,\xi_2 ξ1,ξ2之间有约束(关系)。 套用舒尔补公式: marg掉 ξ 1 \xi_1 ξ1之后,信息被传递到 L 1 和 L 2 L_1和L_2 L1和L2之间了。 T2....
mfc 动态加载dll库,Mat转CImage,读ini配置文件,鼠标操作,在edit控件上画框,调试信息打印
动态加载dll库 h文件中添加 #include "mydll.h" #ifdef UNICODE //区分字符集 #define LoadLibrary LoadLibraryW #else #define LoadLibrary LoadLibraryA #endif // !UNICODEtypedef double(*mydllPtr)(int, int);类内添加: mydllPtr m_mydll; cpp…...
索尼 toio™应用创意开发征文|检测工业平台震动
虽然索尼toio Q宝机器人主要是为儿童教育娱乐开发的,但我认为它在工业等领域也有一定应用潜力。例如,工业领域经常会有某些平面在实际作业中持续震动,导致零件过疲劳、平台失去稳定等问题。而这样的平台往往位于机器内部,从外部很…...
【已解决】 Expected linebreaks to be ‘LF‘ but found ‘CRLF‘.
问题描述 团队都是用mac,只有我自己是windows,启动项目一直报错 Expected linebreaks to be ‘LF‘ but found ‘CRLF‘. 但我不能因为自己的问题去改团队配置,也尝试过该vscode配置默认是LF还是报错 思路 看文章vscode如何替换所有文件的…...
Java8 Lambda.stream.sorted() 方法使用浅析分享
文章目录 Java8 Lambda.stream.sorted() 方法使用浅析分享sorted() 重载方法一升序降序 sorted() 重载方法二升序降序多字段排序 mock代码 Java8 Lambda.stream.sorted() 方法使用浅析分享 本文主要分享运用 Java8 中的 Lambda.stream.sorted方法排序的使用! sorted…...
Neural Networks for Fingerprint Recognition
Neural Computation ( IF 3.278 ) 摘要: 在采集指纹图像数据库后,设计了一种用于指纹识别的神经网络算法。当给出一对指纹图像时,算法输出两个图像来自同一手指的概率估计值。在一个实验中,神经网络使用几百对图像进行训练&…...
ChatGPT推出全新功能,引发人工智能合成声音担忧|百能云芯
人工智能AI科技企业OpenAI公司25日宣布,其聊天应用程序ChatGPT如今具备「看、听、说」能力,至少能够理解口语、用合成语音回应并且处理图像;但专家忧心,以假乱真与深度伪造的乱象可能变本加厉。 国家广播公司新闻网(NBC News)报导…...
Java 实现遍历一个文件夹,文件夹有100万数据,获取到修改时间在2天之内的数据
目录 1 需求2 实现1(第一种方法)2 实现2 (推荐使用这个,快)3 实现3(推荐) 1 需求 现在有一个文件夹,里面会一直存数据,动态的存数据,之后可能会达到100万&am…...
持续集成部署-k8s-命令行工具:基础命令的使用
持续集成部署-k8s-命令行工具:基础命令的使用 1. 资源类型与别名2. 资源操作2.1 创建对象2.2 显示和查找资源2.3 更新资源2.4 修补资源2.5 编辑资源2.6 scale 资源2.7 删除资源3. 格式化输出1. 资源类型与别名 资源类型缩写别名clusterscomponentstatusescsconfigmapscmdaemon…...
政府网站信息内容建设/推广普通话手抄报模板可打印
在程序执行过程中,操作系统会进行线程调度,同一时刻能同时执行的程序数量跟CPU的内核线程数有关,比如4核CPU,同时最多只能有4个线程。Go 语言中的运行时系统也会对goroutine进行调度,调度器会频繁地让goroutine处于中断…...
深圳免费做网站/网络运营seo是什么
7 月 12 日,Python 之父 Guido van Rossum 在 Python 邮件组里发邮称,他将退出 Python 核心决策层,而转居幕后。从 Guido van Rossum 的邮件内容可以看出,他已经厌倦了运营该组织。他在邮件开头写道,「我不想再为 PEP&…...
wordpress 更改标题/平台推广公众平台营销
文章目录一、栈实现计数器思路1、两个栈来保存字符2、比较优先级和计算3、过程会使用到的函数3.1、boolean recognize(char ch)区别是数字还是操作符3.2、int priority(char ch),用来比较优先级3.3、int operateNum(int num1, int num2, char ch)二、用代码实现三、…...
python 视频播放网站开发/衡水seo培训
近日,在某微博上看到有人推荐了这本作者是 雨痕 的《Python学习笔记》,从github上下载下来看了下,确实很不错。 注意,这本学习笔记不适合Python新手学习。 从目录上看,并不能看出这本笔记有何特别之处,但…...
浙江广厦建设职业技术学院招生网站/长尾关键词爱站网
1、确认系统已经安装了SSH。rpm –qa | grep opensshyum install ssh -y ##安装SSH协议2、生成秘钥对ssh-keygen -t rsa -P ##直接回车生成的密钥对:id_rsa和id_rsa.pub,默认存储在用户的目录下 如:/home/oldboy/.ssh。 如下࿱…...
济南网站建设公司晟创未来/软文世界平台
1、高考的失利,只是一时的成败。 2、被生活逼出的动力,你真的有曾感到绝望吗? 3、找到方向很重要,你可能与我一样,只是差了一位引路人。 4、兴趣是最好的老师,持续编程是我唯一坚持超过一年的事情 5、短…...