【C++】:工厂模式

欢迎来到 破晓的历程的 博客

⛺️不负时光,不负己✈️

文章目录

    • 简单工厂模
      • 什么是简单工厂模式?
      • 如何实现简单工厂模式?
    • 工厂方法
    • 抽象工厂模式
    • 总结
      • 简单工厂模式
      • 工厂方法
      • 抽象工厂「Abstract Factory」

简单工厂模

什么是简单工厂模式?

简单工厂模式是一种创新型的设计模式,当有一个基类和若干个派生类形成多态时,用于无须知道类对象是如何被创建的。当用户要创建对象时,直接向工厂申请即可。

如何实现简单工厂模式?

#include<iostream>
#include<string>
#include<functional>
#include<string>
using namespace std;
//基类
class Car
{
public:
	Car(string name)
		:_name(name)
	{}
	//在派生类中,该接口必须被实现
	virtual void show() = 0;
protected:
	string _name;

};
//派生类
class BMW :public Car
{
public:
	BMW(string name)
		:Car(name)
	{}
	void show()
	{
		cout << "获取了一辆宝马汽车: " <<_name<< endl;
	}
private:
};
//派生类
class AoDi :public Car
{
public:
	AoDi(string name)
		:Car(name)
	{}
	void show()
	{
		cout << "获取了一辆奥迪汽车: " <<_name<< endl;
	}
};
enum car_type
{
	bmw,
	aodi,
};
//这就是一个简单工厂类。通过该类,我们不需要知道类对象创建的具体细节。使用时调用即可。
class SimplayFactory
{
public:
	static Car* CreateCar(car_type ct, string name)
	{
		switch (ct)
		{
		case bmw:
			return new BMW(name);
		case aodi:
			return new AoDi(name);
			break;
		default:
			cerr << "输入错误" << endl ;
			break;
		}
	}
};
int main()
{
	
	Car* car1 = SimplayFactory::CreateCar(aodi, "x1");
	car1->show();
}

但是这样实现也有缺点:奥迪和宝马不可能在同一个工厂了被创建。然后这个工厂类也不符合开闭的原则「拓展开放,实现关闭」。基于这样的缺点,工厂方法应运而生。

工厂方法

工厂方法的实现如下:

//工厂方法   基类
class Factory
{
public:
	virtual Car* createCar(string name) = 0;
};
//不同工厂的具体实现  派生类
class BMWFactory :public Factory
{
public:
	Car* createCar(string name)
	{
		return new BMW(name);
	}
};
//不同工厂的具体实现  派生类
class AoDiFactory
{
	Car* createCar(string name)
	{
		return new  AoDi(name);
	}
};
int main()
{
	unique_ptr< Factory> bmwfaty(new BMWFactory());
	unique_ptr<Car>p1(bmwfaty->createCar("x6"));
	p1->show();

}

当我们想增加奔驰的创建工厂的话,根本不需要动宝马和奥迪的工厂,我们只需要从基类中继承实现一个派生类,然后重写creator即可.
但是,一个工厂往往不止制造一产品,我们知道奥迪的车灯很出名,那么奥迪的工厂可能在造车的同时还会生产车灯,如果按照我们的工厂模式的话,就需要创建很多的类,这时就需要抽象工厂模式「在一个工厂内部,允许创建若干种产品」。

抽象工厂模式

代码如下,我们总体上还是使用刚刚的代码。

#include<iostream>
#include<string>
#include<functional>
#include<string>
using namespace std;
//基类
class Car
{
public:
	Car(string name)
		:_name(name)
	{}
	//在派生类中,该接口必须被实现
	virtual void show() = 0;
protected:
	string _name;

};
//派生类
class BMW :public Car
{
public:
	BMW(string name)
		:Car(name)
	{}
	void show()
	{
		cout << "获取了一辆宝马汽车: " <<_name<< endl;
	}
private:
};
//派生类
class AoDi :public Car
{
public:
	AoDi(string name)
		:Car(name)
	{}
	void show()
	{
		cout << "获取了一辆奥迪汽车: " <<_name<< endl;
	}
};
class Light
{
public:
	virtual void show(string name) = 0;
};
class BMWLight :public Light
{
public:
	void show(string name)
	{
		cout << "BMW:" << name << endl;
	}
};
class AoDiLight :public Light
{
public:
	void show(string name)
	{
		cout << "AoDi:" << name << endl;
	}
};
enum car_type
{
	bmw,
	aodi,
};
class Factory
{
public:
	virtual Car* createCar(string name) = 0;
	virtual Light* createCarLight() = 0;
};
class BMWFactory :public Factory
{
public:
	Car* createCar(string name)
	{
		return new BMW(name);
	}
	Light* createCarLight()
	{
		return new BMWLight();
	}

};
class AoDiFactory
{
public:
	Car* createCar(string name)
	{
		return new  AoDi(name);
	}
	Light* createCarLight()
	{
		return new AoDiLight();
	}
};
int main()
{
	unique_ptr< Factory> bmwfaty(new BMWFactory());
	unique_ptr<Car>p1(bmwfaty->createCar("x6"));
	unique_ptr<Light>l1(bmwfaty->createCarLight());
	l1->show("a1");
	p1->show();

}

总结

在历史进步的长河中,一种技术的出现,一定是为了解决前面技术带来的问题「弊端」。接下来,我们分析一下如上几种方案带来的问题:

简单工厂模式

优点
把对象的创建封装到一个接口函数里边,通过传入不同的标记,返回创建的对象。客户不用自己负责new对象。不用了解对象创建的详细过程。
缺点
提供创建对象实例的接口不闭合,不能对外修改关闭。

工厂方法

优点
Factory基类,提供了一个纯虚函数(创建产品)。定义派生类「具体产品的工厂」负责创建对应的产品,可以做到不同的产品,在不同的产品工厂里创建,能够对现有工厂以及产品的修改关闭。
缺点
实际上,很多产品都是有关联关系的,属于一个产品族,不应该放在 不同的工厂里创建,这样不符合实际的产品创建的创建逻辑,二是工厂类太多了,不好维护。

抽象工厂「Abstract Factory」

把有关联的,属于同一个产品系列的的所有产品的创建接口,放在同一个抽象工厂里边,派生类应负责常见该工厂内所有的产品。

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

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

相关文章

【计算机网络】详解数据链路层数据帧Mac地址ARP协议

一、以太网帧 "以太网" 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含了数据链路层的内容&#xff0c;也包含了一些物理层的内容 。例如&#xff1a;规定了网络拓扑结构&#xff0c;访问控制方式&#xff0c;传输速率等&#xff1b;例如以太网中…

【智能算法应用】引力搜索算法求解二维路径规划问题

摘要 引力搜索算法&#xff08;GSA&#xff09;是一种基于引力学说的启发式算法&#xff0c;用于解决复杂的优化问题。本文应用 GSA 于二维路径规划问题&#xff0c;通过优化路径来避开障碍物并达到目标点。实验结果表明&#xff0c;GSA 在路径规划中具有良好的表现&#xff0…

课程作业管理系统的设计与实现(论文+源码)_kaic

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;课程作业管理系统当然也不能排除在外。课程作业管理系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法…

基于Docker安装Grafana及其基本功能

Grafana是一款用Go语言开发的开源数据可视化工具&#xff0c;可以做数据监控和数据统计&#xff0c;带有告警功能。 拉取Grafana镜像 docker pull grafana/grafana 运行镜像 docker run -d -p 3000:3000 --namegrafana grafana/grafana 打开浏览器&#xff0c;访问 http://l…

|动漫爬取|001_djangodjango基于Spark的国漫推荐系统的设计与实现2024_tpd6q1o4

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

to_sql报错not all arguments converted during string formatting

报错&#xff1a; DatabaseError: Execution failed on sql SELECT name FROM sqlite_master WHERE typetable AND name?;: not all arguments converted during string formattingb 报错的代码如下&#xff1a; import pymysql import pandas as pd con pymysql.connect(…

【小技能】一、windows的远程桌面连接

一、简介 windows系列都带有远程桌面连接的程序&#xff1b;学会配置并使用此程序&#xff0c;可以避免让我们每次连接一台新的电脑时去安装远程软件。所以特地前来写下这篇文章&#xff0c;让自己以后忘记了可以来瞧瞧。 二、配置被远程电脑 步骤一&#xff1a;开启远程桌…

诺贝尔物理学奖:机器学习与神经网络的时代

前言 2024年&#xff0c;诺贝尔物理学奖首次颁发给机器学习与神经网络领域的研究者&#xff0c;标志着科学评奖标准的历史性转变。这一决定引发了学术界的广泛关注&#xff0c;也促使人们深入思考科学研究及其应用的未来。 机器学习与物理学的交融 传统上&#xff0c;诺贝尔物…

前端开发设计模式——命令模式

目录 一、命令模式的定义和特点 1.定义&#xff1a; 2. 特点&#xff1a; 二、命令模式的结构与原理 1.结构&#xff1a; 2.原理&#xff1a; 三、命令模式的实现方式 1.定义接口命令&#xff1a; 2.创建具体的命令类&#xff1a; 3.定义接收者&…

【MySQL 保姆级教学】数据库的操作(3)

数据库的操作 1. 创建数据库2. 创建数据库的案例3. 字符集和校验规则3.1 查看系统默认字符集以及校验规则3.2 查看数据库支持的字符集3.3 查看数据库支持的字符集校验规则3.4 校验规则对数据库的影响 4. 操纵数据库4.1 查看数据库4.2 显示创建语句4.3 修改数据库4.4 删除数据库…

OpenCV打开摄像头或视频

文章目录 1. 视频读取流程创建视频对象设置摄像头参数循环检查是否初始化成功并读取读取视频释放摄像头删除建立的全部窗口cv2.CAP_DSHOW设置后帧率变慢的问题 2.所有python实现代码参考文献 1. 视频读取流程 创建视频对象 cap cv2.VideoCapture(videoPath) #加载视频 cap …

【风控安全产品系统架构设计的一些思考】

随着互联网的不断发展和普及&#xff0c;信息安全和风险控制成为了各行各业关注的焦点之一。在这样的背景下&#xff0c;风控安全产品成为了保障企业信息资产安全的重要手段之一。本文将探讨风控安全产品系统架构设计的一些关键思考和实践经验。 1. 深度了解业务需求 在设计…

FFmpeg的简单使用【Windows】

目录 一、视频生成图片 静态图片 转码过程 动态图片gif 二、图片生成视频 三、FFmpeg常用参数命令 3.1 主要参数 3.1.1、-i 3.1.2、-f 3.1.3、-ss 3.1.4、-t 3.2 音频参数 3.2.1、-aframes 3.2.2、 -b:a 3.2.3、-ar 3.2.4、-ac 3.2.5、-acodec 3.2.6、-an 3…

未来汽车究竟该是什么样子?

24年10月14日&#xff0c;在中国&#xff08;深圳&#xff09;机器视觉展暨机器视觉技术及工业应用研讨会上&#xff0c;同行者分享了未来智能座舱应该长什么样子。 受此启发&#xff0c;个人觉得当前大多数新能源车都极力想做出电动感&#xff0c;但是布局传统没跳出来&#…

【Golang】Go 语言中的 time 包详解:全面掌握时间处理与应用

在 Go 语言中&#xff0c;time 包提供了强大的时间处理功能&#xff0c;适用于各种场景&#xff1a;获取当前时间、格式化和解析时间、计算时间间隔、设置定时器、处理超时等。在开发过程中&#xff0c;熟练掌握 time 包能够帮助我们轻松处理时间相关的操作&#xff0c;尤其是定…

【大模型理论篇】大模型中的强化学习RLHF(PPO)、DPO(Direct Preference Optimization)等概念的理解与解析

1. “人类对齐&#xff08;Human Alignment&#xff09;”背景介绍 本文主要针对大模型训练过程中的PPO(Proximal Policy Optimization)、DPO(Direct Preference Optimization)等概念进行解释和分析&#xff0c;更确切的说是在“人类对齐&#xff08;Human Alignment&#xff0…

aosp14分屏分割线区域部分深入剖析-framework实战干货

背景&#xff1a; 原来在学习分屏课程期间&#xff0c;当时没有对分屏分割线的区域部分进行详细介绍。 本篇文章就针对这个块的知识进行详细的补充讲解&#xff0c;首先可以通过下图所示分割线情况&#xff0c;这样有一个初步的认识 简单说分屏情况下分割线是可以拖拉到不同…

社交媒体对人际关系的影响:Facebook的案例分析

随着社交媒体的快速发展&#xff0c;人们的沟通方式和人际关系发生了深刻变化。作为全球最大的社交网络之一&#xff0c;Facebook在这一进程中扮演了重要角色。本文将分析Facebook如何影响人际关系&#xff0c;包括沟通方式的转变、情感连接的变化以及社交互动的质量。 1. 沟通…

无极低码课程【redis windows下服务注册密码修改】

下载Windows版本的Redis linux环境 (自行下载) 1.打开官网https://redis.io/downloads/ windows环境 1.打开github https://github.com/microsoftarchive/redis/releases 然后选择你喜欢的版本zip或msi下载 2.这里下载zip版,解压后后,打开安装目录 3.双击redis-server…

Xcode使用Instruments的dsym还原符号堆栈问题

文章目录 设置符号表的步骤参考资料 设置符号表的步骤 instruments 的 Settings 中&#xff0c;可以设置符号表的搜索路径 没有生效的话&#xff0c;继续看 File 里面的 Symbols - 出现弹窗后点击 Add Symbols - 然后再点击 Apply。 参考资料 https://xjkstar.github.i…