【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」

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

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

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

相关文章

ps提示不能使用移动工具,因为目标通道被隐藏的解决办法

解决&#xff1a;按F7&#xff0c;或者从窗口把图层打开 按图示找到快速蒙版图层。它可能被隐藏或以特殊图标显示。右键删除或者拖到右下角垃圾桶里

小猿口算炸鱼脚本

目录 写在前面&#xff1a; 一、关于小猿口算&#xff1a; 二、代码逻辑 1.数字识别 2.答题部分 三、代码分享&#xff1a; 补充&#xff1a;软件包下载 写在前面&#xff1a; 最近小猿口算已经被不少大学生攻占&#xff0c;小学生直呼有挂。原本是以为大学生都打着本…

从融资烧钱到商业落地:中国AI大模型步入「实战期」

在AI还尚且未达到生产力工具的时候&#xff0c;没人能知道怎样的基础模型会是尽头&#xff0c;以及对付费客户而言&#xff0c;他们如何才能将这笔投入转化为真实营收。 而对于大模型究竟什么能盈利&#xff0c;目前国内的任何一家都未表过态。或者说&#xff0c;这不是一个当…

从0开始深度学习(11)——多层感知机

前面介绍了线性神经网络&#xff0c;但是线性模型是有可能出错的&#xff0c;因为线性模型意味着是单调假设&#xff0c;但是现实中往往很复杂。例如&#xff0c;我们想要根据体温预测死亡率。 对体温高于37摄氏度的人来说&#xff0c;温度越高风险越大。 然而&#xff0c;对体…

MySQL插入优化-性能对比

插入优化主要包括&#xff1a; 批量插入条数据&#xff0c;而不是单个记录逐条插入。手动提交事务&#xff0c;避免自动提交事务带来的额外开销。使用load命令从本地文件导入。 性能对比 创建数据库表 CREATE TABLE if not exists tb_sku ( id int(20) …

facefusion,使用CPU实现一键图片、视频换脸,无需显卡,无限时长(附下载即用的整合包)

FaceFusion 是一种利用人工智能技术将两张或多张人脸融合在一起的图像处理技术。这种技术通过面部特征的识别和重构&#xff0c;将不同的人脸混合成一张新的脸&#xff0c;生成的图像看起来像是这些人脸的融合体。 FaceFusion使用深度学习算法&#xff0c;来捕捉人脸的细节和特…

OpenCV答题卡识别

文章目录 一、基本流程二、代码实现1.定义函数2.图像预处理&#xff08;1&#xff09;高斯模糊、边缘检测&#xff08;2&#xff09;轮廓检测&#xff08;3&#xff09;透视变换&#xff08;4&#xff09;阈值处理和轮廓检测 3.筛选和排序选项轮廓4.判断答案5.显示结果 三、总结…

YOLOv11改进有效系列目录 - 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制 - 针对多尺度、小目标、遮挡、恶劣天气等问题

目标检测作为计算机视觉领域的一项核心任务&#xff0c;极大地推动了整个领域的发展。它不仅是其他许多视觉任务的基础工具&#xff0c;还在学术研究和实际应用之间架起了一座桥梁。目标检测的主要任务是识别和定位图像或视频中的特定对象&#xff0c;通常需要模型能同时处理多…

C++ | Leetcode C++题解之第476题数字的补数

题目&#xff1a; 题解&#xff1a; class Solution { public:int findComplement(int num) {int highbit 0;for (int i 1; i < 30; i) {if (num > (1 << i)) {highbit i;}else {break;} }int mask (highbit 30 ? 0x7fffffff : (1 << (hig…

【DBA Part01】国产Linux上安装Oracle进行数据迁移

内容如下&#xff1a; 1.1.生产环境RHEL/OEL Linux8Oracle11gR2安装配置 1.2.国产麒麟操作系统Oracle11gR2安装配置 1.3.国产麒麟操作系统Oracle11gR2 RAC集群安装配置 1.4.Oracle11gR2迁移到国产麒麟操作系统&#xff08;单机/RAC&#xff09; 本阶段课程项目需求说明&am…

零一万物 Yi-Lightning:超越 GPT-4o 冲击全球榜单;阿里国际 Marco 翻译大模型发布丨 RTE 开发者日报

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。 我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 …

CEEMDAN +组合预测模型(Transformer - BiLSTM + ARIMA)

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现&#xff08;一&#xff09;EMD-CSDN博客 EMD、EEM…

具备技术二:正则表达式

一、C正则库 regex 用于报文的解析。 使用接口&#xff1a;bool regex_match(const string &src, smatch &matches, regex &e); src&#xff1a;要解释的字符串。 smatch&#xff1a;一个类似于数组的结构&#xff0c;用于存储一个个解释之后的字符串。 matche…

鸿蒙网络编程系列3-TCP客户端通讯示例

1. TCP简介 TCP协议是传输层最重要的协议&#xff0c;提供了可靠、有序的数据传输&#xff0c;是多个广泛使用的表示层协议的运行基础&#xff0c;相对于UDP来说&#xff0c;TCP需要经过三次握手后才能建立连接&#xff0c;建立连接后才能进行数据传输&#xff0c;所以效率差了…

Android -- [SelfView] 多动画效果图片播放器

Android – [SelfView] 多动画效果图片播放器 效果&#xff08;录制的有点卡&#xff09; 1. 引用&#xff1a; <com.nepalese.virgolib.widget.image.BaseImageViewandroid:id"id/base_image"android:layout_width"match_parent"android:layout_heigh…

AD画图的使用

一、新建工程 二、绘制原理图 1、原理图搜索方法&#xff1a; https://www.ti.com/lit/ds/symlink/tlv1117.pdf?ts1729143086540&ref_urlhttps%253A%252F%252Fwww.mouser.tw%252F www.alldatasheet.com 2、绘图步骤&#xff1a; 注&#xff1a;管脚四点朝外

2024软考网络工程师笔记 - 第5章.无线通信网

文章目录 移动通信与 5G1️⃣移动通信2️⃣移动通信制式3️⃣5G 应用场景与关键技术 &#x1f551;WLAN 通信技术1️⃣WLAN 通信技术 &#x1f552;WLAN 频谱与信道&#xff08;高频考点&#xff09;1️⃣WLAN 网络分类2️⃣ISM频段3️⃣不重叠信道&#xff08;重点&#xff09…

uniapp 省、市、区、乡镇 数据层级选择插件 Ba-DataPicker

Ba-DataPicker 是一款uniapp数据层级选择弹窗插件。支持省市区乡四级&#xff1b;支持自定义数据。 支持省、市、区、乡镇四级支持自定义数据支持字母检索 截图展示 支持定制、本地包、源码等&#xff0c;有建议和需要&#xff0c;请点击文章结尾“Uniapp插件开发”联系我&am…

人脸识别-特征算法

文章目录 一、LBPH算法1.基本原理2.实现步骤3.代码实现 二、Eigenfaces算法1.特点2.代码实习 三、FisherFaces算法1.算法原理2.算法特点3.代码实现 四、总结 人脸识别特征识别器是数字信息发展中的一种生物特征识别技术&#xff0c;其核心在于通过特定的算法和技术手段&#xf…

代码随想录算法训练营第八天(1)|哈希表理论基础

文档讲解&#xff1a;代码随想录 难度&#xff1a;有一点 哈希表理论基础 哈希表 首先什么是哈希表&#xff0c;哈希表&#xff08;英文名字为Hash table&#xff0c;国内也有一些算法书籍翻译为散列表&#xff0c;大家看到这两个名称知道都是指hash table就可以了&#xff0…