当前位置: 首页 > news >正文

C++|设计模式(三)|抽象工厂模式

抽象工厂模式仍然属于创建型模式,我们在【简单工厂和工厂方法模式】这篇文章中,描述了简单工厂和工厂方法模式,并在文末,简单介绍了工厂方法模式的局限性。

本文将通过汽车工厂的例子继续来阐述使用抽象工厂模式相比较于工厂方法模式的优势。

文章目录

  • 工厂方法模式回顾
  • 抽象工厂模式
    • 代码使用
    • 抽象工厂的局限性

工厂方法模式回顾

工厂方法模式通过允许类将实例化延迟到子类中来实现,使得增加新的产品类不需要修改现有系统的代码。例如,一个汽车制造商需要不同类型的汽车,如宝马、奥迪等,每种汽车的制造过程可能不同:

#include <iostream>
#include <string>
#include <memory>
using namespace std;class Car {
public:Car(string name) : name_(name) { }virtual ~Car(){}virtual void show() = 0;
protected:string name_;
};class Bmw : public Car {
public:Bmw(string name) : Car(name) { }void show() { cout << "获得一辆宝马汽车 " << name_ <<endl; }
};class Audi : public Car {
public:Audi(string name) : Car(name) { }void show() { cout << "获得一辆奥迪汽车 " << name_ << endl; }
};//工厂方法
class Factory {
public:virtual ~Factory() {}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); }
};int main () {unique_ptr<Factory> bmwFactory(new BMWFactory());unique_ptr<Factory> audiFactory(new AudiFactory());unique_ptr<Car> p1(bmwFactory->createCar("X6"));unique_ptr<Car> p2(audiFactory->createCar("A8"));p1->show();p2->show();return 0;
}

现在,我们考虑这样一种情况,如果我们现在要生产的产品是一组有关联的产品簇怎么办?难道我们像工厂方法一样,又新建立一个工厂来生产该产品吗?

比如说,我们之前有了奥迪工厂和宝马工厂,现在我们需要生产奥迪车灯和宝马车灯,难道又建立奥迪车灯工厂吗?

这样的话,最后我们需要管理的工厂(类)那也太多了,所以,很容易想到:

我们应该对一组有关联关系的产品簇提供产品对象的统一创建。这就是抽象工厂模式。

抽象工厂模式

我们把之前的工厂方法类写成抽象工厂类,并且里面提供创建车灯的方法,

并且,我们直接在宝马工厂和奥迪工厂去创建车灯:

//系列产品一:汽车
class Car {
public:Car(string name) : name_(name) { }virtual ~Car(){}virtual void show() = 0;
protected:string name_;
};
class Bmw : public Car {
public:Bmw(string name) : Car(name) { }void show() { cout << "获得一辆宝马汽车 " << name_ <<endl; }
};
class Audi : public Car {
public:Audi(string name) : Car(name) { }void show() { cout << "获得一辆奥迪汽车 " << name_ << endl; }
};
//系列产品二:车灯
class Light {
public:virtual ~Light() {}virtual void show() = 0;
};
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 ~AbstractFactory() {}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();}
};

代码使用

int main () {unique_ptr<AbstractFactory> bmwFactory(new BMWFactory());unique_ptr<AbstractFactory> audiFactory(new AudiFactory());unique_ptr<Car> p1(bmwFactory->createCar("X6"));unique_ptr<Car> p2(audiFactory->createCar("A8"));unique_ptr<Light> l1(bmwFactory->createCarLight());unique_ptr<Light> l2(audiFactory->createCarLight());p1->show();l1->show();p2->show();l2->show();return 0;
}

抽象工厂的局限性

我们设想这样一种场景,比如说我们的宝马工厂需要创建一个新的类对象(产品),但是奥迪工厂并不需要,但是如果宝马工厂想要创建该类,
我们也比赛在抽象工厂类中去定义这样一个虚函数,尽管奥迪工厂并不需要创建该类对象,他还是不得不去重写该虚函数。这样是不符合逻辑的。

总结:
简单工厂Simple Factory:
优点:把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象,用户不用自己负责new对象,不用了解对象创建的详细过程
缺点:提供创建对象实例的接口函数不闭合,不能对修改关闭
工厂方法Factory Method:
优点:Fatcory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品,可以做到不同的产品,在不同的工厂里面创建,能够对现有工厂,以及产品的修改关闭
缺点:实际上,很多产品是有管理关系的,属于一个产品簇,不应该放在不同的工厂里面去创建,这样一是不符合实际的产品对象创建逻辑,二是工厂类太多了,不好维护
抽象工厂Abstract Factory
优点:把有关联关系的,属于一个产品簇的所有产品创建的接口函数,放在一个抽象工厂里面AbstractFactory类,派生类(具体产品的工厂)应该负责创建该产品簇里面所有的产品。

相关文章:

C++|设计模式(三)|抽象工厂模式

抽象工厂模式仍然属于创建型模式&#xff0c;我们在【简单工厂和工厂方法模式】这篇文章中&#xff0c;描述了简单工厂和工厂方法模式&#xff0c;并在文末&#xff0c;简单介绍了工厂方法模式的局限性。 本文将通过汽车工厂的例子继续来阐述使用抽象工厂模式相比较于工厂方法…...

AVB协议分析(一) FQTSS协议介绍

FQTSS协议介绍 一、AVB整体架构二、概述三、协议作用及作用对象四、协议的实现五、参考文献&#xff1a; 一、AVB整体架构 可见FQTSS位于MAC层的上面&#xff0c;代码看不懂&#xff0c;咱们就从最底层开始&#xff0c;逐层分析协议&#xff0c;逐个击破&#xff0c;慢就是快。…...

一个程序员的牢狱生涯(44)询问

星期一 询 问 在号子里开始了下午坐班的时候,过道内的大铁栅栏被管教打开,我听到开锁的声音后,心里变得激动起来。盼望着脚步声能停在我们的号子门口,然后打开铁门,喊一声“眼镜,出来!”。 通道内这次进来的是秦所,但他并没有在我们号子门口停留,只是在走过的时候,低…...

刷爆leetcode第六期

题目一 用队列实现栈 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int pop() 移除…...

汇舟问卷:国外问卷调一天900

大家好&#xff0c;我是汇舟问卷&#xff0c;专注于国外问卷调查互联网项目。夏天已经来临&#xff0c;您是否在三伏天顶着大太阳上班&#xff0c;汗水浸湿了衣襟&#xff0c;却依然要面对繁琐的工作和无尽的压力&#xff1f; 在这个炎热的季节里&#xff0c;我们都渴望找到一…...

openresty完美替代nginx

OpenResty相较于Nginx&#xff0c;其优势主要体现在以下几个方面&#xff1a; 1、Lua脚本支持&#xff1a;OpenResty内置了LuaJIT&#xff08;Lua的即时编译器&#xff09;&#xff0c;使得用户可以直接在Nginx配置文件中使用Lua脚本&#xff0c;这样可以实现更复杂的业务逻辑…...

深入解析:Element Plus 与 Vite、Nuxt、Laravel 的结合使用

在现代前端开发中&#xff0c;选择合适的工具和框架来提高开发效率和应用性能是至关重要的。 Element-Plus 是一个基于 Vue.js 3.0 的流行 UI组件库&#xff0c;它可以与多种前端和后端框架结合使用&#xff0c;如 Vite、Nuxt 和 Laravel。本文将深入探讨这三者与 Element Plus…...

使ssh连接Linux服务器一直不掉线

怎么可以使ssh连接Linux服务器一直不掉线 解决方法&#xff1a; vim /etc/profile在/etc/profile中的TMOUT改为0 export TMOUT0最后 source /etc/profile就可以了...

2024-05-29 blue-VH-driver-对外接口的并行调用-设计与思考

摘要: VH的driver的对外接口, 要做到可以并行&#xff0c;也就是两个不同的线程&#xff0c;分别调用&#xff0c;不能互相阻塞。 本文记录对其的思考和设计。 上下文: 2024-05-28 blue-VH-driver-需求分析及问题分析-CSDN博客 2024-05-27 blue-vh-问题点-CSDN博客 2024-05…...

ubuntu安装

1.下载镜像文件 2.打开VMware并新建虚拟机 版本选择Ubuntu 64位 磁盘容量改为40GB 点击自定义硬件&#xff0c;点击新CD/DVD&#xff08;SATA&#xff09;&#xff0c;连接选择ISO映像文件&#xff0c;找到之前下载的Ubuntu镜像文件&#xff0c;然后关闭选项卡。 3.开启虚拟机…...

Rosetta PyRosetta 源码包 安装包 下载

--- pyrosetta_src.zip包含以下包&#xff1a; | --- PyRosetta4.Debug.python27.ubuntu.release-185.tar.bz2 | --- PyRosetta4.Release.python27.linux.release-215.tar.bz2 | --- PyRosetta4.Release.python38.ubuntu.release-349.tar.bz2 --- pyrosetta_whl.zip包含…...

C++ 进阶(3)虚函数表解析

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、虚函数表 二、单继承&#xff08;无虚函数覆盖&#xff09; 继承关系表&#xff1a; 对于实例&#xff1a;derive d 的虚函数表&#xff1a; 对于实例&#xff1a;b…...

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测 亮点&#xff1a; 输出多个评价指标&#xff1a;R2&#xff0c;RMSE&#xff0c;MSE&#xff0c;MAPE和MAE 满足需求&#xff0c;分开运行和对比的都有对应的主函数&#xff1a;main_BP, main_SBOA, main_BPvsBP_SB…...

kafka-主题创建(主题操作的命令)

文章目录 1、topic主题操作的命令1.1、创建一个3分区1副本的主题1.1.1、获取 kafka-topics.sh 的帮助信息1.1.2、副本因子设置不能超过集群中broker的数量1.1.3、创建一个3分区1副本的主题1.1.4、查看所有主题1.1.5、查看主题详细描述 1、topic主题操作的命令 kafka发送消息会存…...

[日常开发] 数据库主从延迟问题

MySQL数据库主从延迟问题 无论是学习还是工作中&#xff0c;MySQL数据库的使用都十分地广泛。在业务中&#xff0c;数据库也会以集群的形式使用&#xff0c;所以会涉及到主从问题。 问题描述 在使用MySQL数据库的时候&#xff0c;在service的方法中首先向A数据表批量插入了数…...

Python高层解雇和客户活跃度量化不确定性模型

&#x1f3af;要点 &#x1f3af;量化不确定性模型&#xff1a;&#x1f58a;模型检测短信编写者行为变化 | &#x1f58a;确定&#xff08;商业领域中&#xff09;竞争性替代方案 | &#x1f58a;确定作弊供词真实比例 | &#x1f58a;学生考试作弊 | &#x1f58a;确定零部件…...

【IOT】OrangePi+HomeAssistant+Yolov5智能家居融合

前言 本文将以OrangePi AIpro为基础&#xff0c;在此基础构建HomeAssistant、YOLO目标检测实现智能家居更加灵活智能的场景实现。 表头表头设备OrangePi AIpro(8T)系统版本Ubuntu 22.04.4 LTSCPU4核64位处理器 AI处理器AI算力AI算力 8TOPS算力接口HDMI2、GPIO接口、Type-C、M.2…...

Python 点云裁剪

点云裁剪 一、介绍1.1 概念1.2 函数讲解二、代码示例2.1 代码实现2.2 代码讲解三、结果示例一、介绍 1.1 概念 点云裁剪 :根据待裁剪对象的多边形体积(json文件)实现点云的裁剪。 1.2 函数讲解 下面代码示例中主要用到了两个函数。 读取待裁剪对象的多边形体积信息(json文…...

Presto 从提交SQL到获取结果 源码详解(2)

逻辑执行计划&#xff1a; //进入逻辑执行计划阶段 doAnalyzeQuery().new LogicalPlanner().plan(analysis);//createAnalyzePlan createAnalyzePlan(analysis, (Analyze) statement);//返回RelationPlan&#xff0c;&#xff08;返回root根节点&#xff0c;逻辑树上包含输出字…...

Python的类全面系统学习

文章目录 1. 基本概念1.1 类&#xff08;Class&#xff09;1.2 对象&#xff08;Object&#xff09; 2. 类的属性和方法3. 类的继承3.1 继承的概念3.2 单继承3.3 多重继承 4. 方法重写与多态4.1 方法重写4.2 多态 5. 特殊方法与运算符重载5.1 特殊方法&#xff08;魔法方法&…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...