C++之工厂模式

目录

一、为什么要使用工厂模式

优点

缺点

二、简单工厂(Simple Factory)

好处:

不足:

三、工厂方法:

好处:

不足:

四、抽象工厂(Abstract   Factory)


一、为什么要使用工厂模式

主要是对对象的创建进行了一个封装;
因此也属于创建型模式。

目的:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

优点

  1. 一个调用者想创建一个对象,只要知道其名称就可以了;
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;
  3. 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

二、简单工厂(Simple Factory)

把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象

好处:

可以看到,简单工厂可以做到,让用户创建对象的时候只需要知道对象的名称(BMWAUDI)就好,而不需要关心创建对象的细节(BMW是如何建造的、型号是什么等等细节)。

不足:


每当我们想要扩展对象的时候(增加BENZ的对象)就需要在SimpleFactory类中添加代码,增加switch后面的case选项。这样一来,就需要修改源代码。灵活性非常的差!!!

那么,能不能做到添加对象的时候,不对现有代码进行修改呢?(也就是我们开发软件时候需要遵守的开-闭原则)

这便是接下来工厂方法

三、工厂方法:

一个派生类就代表着一个工厂,每个工厂都有具体要生产的产品。

FActory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品,

//工厂方法:
class Factory
{
public:
	virtual Car* createCar(string name) = 0;
};
//宝马工厂
class BMWFactory : public Factory
{
public:
	Car* createCar(string name) 
	{
		return new BMW(name);
	}
};
//奥迪工厂
class AudiFactory : public Factory
{
public:
	Car* createCar(string name)
	{
		return new Audi(name);
	}
};

void main()
{
	Factory* bmwfty = new BMWFactory();
	Factory* audifty = new AudiFactory();

	Car* p1 = bmwfty->createCar("X6");
	Car* p2 = audifty->createCar("A6");

	p1->show();
	p2->show();
}

当我们想要增加新的工厂:比如说奔驰工厂的时候,根本不用去管宝马和奥迪,只需要增加一个新的工厂就行了,所以说是符合了软件设计的          “开闭原则”   : 对已有的功能关闭,对扩展开放

好处:

可以做到不同的产品,在不同的工厂里面创建(模块化非常清晰),能够对现有工厂,以及产品的修改关闭

不足:

实际上,很多产品是有关联关系的,属于一个产品簇,不应该放到不同的工厂里面去创建,这样
一是不符合实际的产品对象创建逻辑,二是工厂类太多了,不好维护

四、抽象工厂(Abstract   Factory)

应用于有关联关系的产品

上面的简单工厂已经能够满足基本的要求了,但是在实际生活中,比如宝马企业,不止有汽车,还有别的系列产品,比如:车灯、轮胎。。。也就是跟汽车有关的一组产品

代码

继承关系如下:

//系列产品1:
class Car 
{
public:
	Car(string name):_name(name)
	{}
	virtual void show()
	{}

protected:
	std::string _name;
};

class BMW:public Car
{
public:
	BMW(string name):Car(name)
	{}
	void show() {
		cout << "这是一辆宝马" << endl;
	}
};

class Audi :public Car
{
public:
	Audi(string name) :Car(name)
	{}
	void show() {
		cout << "这是一辆奥迪" << endl;
	}
};
//系列产品 2:
class Light
{
public:
	virtual void show()
	{
	}
};
class BmwLight :public Light
{
public:
	void show()
	{
		cout << "BMW 的 Light" << endl;
	}
};
class AudiLight :public Light
{
public:
	void show()
	{
		cout << "Audi 的 Light" << endl;
	}
};

抽象工厂的实现:

//工厂方法 ==>> 抽象工厂(对一组关联关系的产品簇提供产品对象的统一创建)
class AbstractFactory
{
public:
	virtual Car* createCar(string name) = 0;//工厂方法  创建汽车
	virtual Light* createLight() = 0;// 工厂方法  创建汽车关联的产品,车灯
};
//宝马工厂
class BMWFactory : public AbstractFactory
{
public:
	Car* createCar(string name) 
	{
		return new BMW(name);
	}
	Light* createLight()
	{
		return new BmwLight();
	}
};
//奥迪工厂
class AudiFactory : public AbstractFactory
{
public:
	Car* createCar(string name)
	{
		return new Audi(name);
	}
	Light* createLight()
	{
		return new AudiLight();
	}
};

使用:

void main()
{
	AbstractFactory* bmwfty = new BMWFactory();
	AbstractFactory* audifty = new AudiFactory();

	Car* p1 = bmwfty->createCar("X6");
	Car* p2 = audifty->createCar("A6");
	p1->show();
	p2->show();

	Light* l1 = bmwfty->createLight();
	Light* l2 = audifty->createLight();
	l1->show();
	l2->show();
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【工具推荐】企业微信、企业飞书接口调用工具

github地址: GitHub - fasnow/idebug: 企业微信、企业飞书接口调用工具。 简介 企业微信、企业飞书接口调用工具。 使用方法 wechat模块 使用use wechat 选择模块。 首先设置corpid和corpsecret&#xff0c;如有需要可以设置代理&#xff0c;之后再执行run命令。 导出通信…

chatgpt 与传统3D建模对比分析

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 随着人工智能技术的发展&#xff0c;越来越多的领域正逐渐被AI模型所取代。ChatGPT作为一种自然语言处理技术&#xff0c;越来越为人们所熟悉。最近&#xff0c;一些3D建模领域的专家想知道ChatGPT是否可以取代传统的手动3D建…

在?聊聊浏览器事件循环机制

目录 前言 同步/异步编程模型 同步 异步 JS异步模型 调用栈 任务队列 宏任务队列 微任务队列 微任务API 事件循环 队列优先级 混合队列 事件循环实现 总结 参考文章 Event-Loop可视化工具 前言 JS是单线程语言&#xff0c;在某个时间段只能执行一段代码。这…

IP地址定位技术为何如此准确?揭秘背后原理

据最新数据显示&#xff0c;全球互联网用户数量已突破50亿。为确保用户安全和提供个性化服务&#xff0c;IP地址定位技术愈发重要。但你是否好奇&#xff0c;为何IP地址定位如此准确&#xff1f;今天我们将揭秘其背后原理。 IP地址定位技术利用了多种方法来确定用户的地理位置。…

mac苹果电脑,怎么把mkv转换mp4格式

mac苹果电脑&#xff0c;怎么把mkv转换mp4格式&#xff1f;如果你是一名mac苹果电脑的用户&#xff0c;在电脑上下载到mkv格式的视频后会发现它使用起来非常的麻烦&#xff0c;甚至不能直接打开播放。mkv其实也是一种时间比较久远的视频文件格式&#xff0c;但是不知道是什么原…

MAC电脑查看SHA256方式

背景 现在很多网站下载大文件时&#xff0c;以往通过查看文件大小来确定是否下载正确&#xff0c;但是很多情况下&#xff0c;文件下载后大小差不多&#xff0c;但是很多时候却时候出现无法安装的问题&#xff0c;有可能还是下载的文件出现错误&#xff0c;导致文件无法正常使…

研发效能认证学员作品:使用威胁建模进行DevSecOps实践

一、从DevOps到 DevSecOps 作者&#xff1a; 姚圣伟&#xff08;现就职天津引元科技 天津市区块链技术创新中心&#xff09; 研发效能&#xff08;DevOps&#xff09;工程师认证学员 DevOps 最开始最要是强调开发和运维的协作与配合&#xff0c;至今&#xff0c;已不仅仅涉及开…

【运维工程师学习二】OS系统管理

【运维工程师学习二】OS系统管理 1、操作系统管理2、进程管理3、进程的启动4、进程信息的查看4.1、STAT 进程的状态&#xff1a;进程状态使用字符表示的&#xff08;STAT的状态码&#xff09;,其状态码对应的含义&#xff1a;4.2、ps命令常用用法&#xff08;方便查看系统进程&…

stm32(独立看门狗和窗口看门狗)

独立看门狗介绍 什么是看门狗&#xff1f; 在由单片机构成的微型计算机系统中&#xff0c;由于单片机的工作常常会受到来自外界电磁场的干扰&#xff0c;造 成程序的跑飞&#xff0c;而陷入死循环&#xff0c;程序的正常运行被打断&#xff0c;由单片机控制的系统无法继续工作…

Vue3 网络请求——axios 高级用法之 axios 拦截器实战与并发请求

文章目录 &#x1f4cb;前言&#x1f3af;关于拦截器&#x1f3af;项目创建&#x1f3af;代码分析&#x1f3af;补充&#xff1a;并发请求&#x1f9e9;axios.all() 和 Promise.all() 的区别 &#x1f4dd;最后 &#x1f4cb;前言 Axios 是一个流行的基于 Promise 的 HTTP 客户…

spring系列所有漏洞vulhub复现CVE-2022-22978、CVE-2022-22963、CVE-2022-22965、CVE-2018-1273

文章目录 CVE-2022-22978 Spring-security 认证绕过漏洞漏洞描述:复现&#xff1a; CVE-2022-22963漏洞描述:复现&#xff1a; 提提神Spring框架Data Binding与JDK 9导致的远程代码执行漏洞&#xff08;CVE-2022-22965&#xff09;漏洞描述:复现&#xff1a; Spring Data Commo…

机器学习笔记:随机森林

1 集成学习 集成学习通过构建多个学习器采用加权的方式来完成学习任务一般来讲&#xff0c;多个学习器同属于一种模型&#xff0c;比如决策树&#xff0c;线性模型&#xff0c;而不会交叉用多种模型为了保证集成学习的有效性&#xff0c;多个弱分类器之间应该满足两个条件 准确…

【附3.7安装包】python安装包下载及安装(超详细)

python3.7链接&#xff1a;https://pan.baidu.com/s/1Ett3XBMjWhkVOxkOU8NRqw?pwdqz3l 提取码&#xff1a;qz3l 今日资源&#xff1a;Python 适用系统&#xff1a;WINDOWS ​ Python 3.7.0 软件介绍&#xff1a; Python是一款通用型的计算机程序设计语言&#xff0c;Pytho…

4.5 x64dbg 探索钩子劫持技术

钩子劫持技术是计算机编程中的一种技术&#xff0c;它们可以让开发者拦截系统函数或应用程序函数的调用&#xff0c;并在函数调用前或调用后执行自定义代码&#xff0c;钩子劫持技术通常用于病毒和恶意软件&#xff0c;也可以让开发者扩展或修改系统函数的功能&#xff0c;从而…

unbuntu 22.04 安装和卸载企业微信

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 记录有关在ubuntu22.04上安装和卸载企业微信 以及企业微信无法打开问题处理 1. 正文 1.1 安装 下载wine环境 http://archive.ubuntukylin.com/softwar…

【JMeter】同步定时器Synchronizing Timer集合点功能

LoadRunner 中有一个可以设置集合点的功能&#xff0c;顾名思义是设置多个虚拟用户等待到一个时间点&#xff0c;都到齐集合后一起发请求达到并发的目的 集合点是什么意思呢&#xff1f; 阻塞线程&#xff0c;直到指定的线程数量到达后&#xff0c;再一起释放&#xff0c;可以…

这一次,Python 真的有望告别 GIL 锁了?

Python 中有一把著名的锁——全局解释器锁&#xff08;Global Interpreter Lock&#xff0c;简写 GIL&#xff09;&#xff0c;它的作用是防止多个本地线程同时执行 Python 字节码&#xff0c;这会导致 Python 无法实现真正的多线程执行。&#xff08;注&#xff1a;本文中 Pyt…

Java设计模式之结构型-代理模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 1、静态代理类图 2、动态代理类图 三、角色设计 四、案例分析 1、静态代理 2、JDK动态代理 3、Cglib动态代理 五、总结 一、基础概念 代理模式是一种结构型设计模式&#xff0c;它用一个代理对象来封装一个目标对象&#xff0c;通常…

NP问题的通俗解释

本博客参考&#xff1a; https://zhuanlan.zhihu.com/p/348250098https://zhuanlan.zhihu.com/p/348020672https://zhuanlan.zhihu.com/p/260512272以及相关的1-6。 是什么 NP的全称是Non Deteministic Polynomial&#xff0c;是线性所不能判别的问题的集合。 NP这个东西是…

使用RabbitMQ

使用RabbitMQ 1 Docker安装RabbitMQ 1.1 安装RabbitMQ # 下载含有管理页面的镜像 docker pull rabbitmq:3.8.8-management# 创建容器 # 5672&#xff1a;应用访问端口&#xff1b;15672&#xff1a;控制台Web端口号&#xff1b; docker run -itd \ --namemy-rabbitmq \ --re…