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

抽象工厂模式 创建性模式之五

        在看这篇文章之前,请先看看“简单工厂模式”和“工厂方法模式”这两篇博文,会更有助于理解。我们现在已经知道,简单工厂模式就是用一个简单工厂去创建多个产品,工厂方法模式是每一个具体的工厂只生产一个具体的产品,然后这些具体的工厂都以一个抽象的工厂作为基类。

        那么抽象工厂模式是什么呢,抽象工厂模式让一个具体的工厂可以生产多类的产品,也就是它从工厂方法模式种的一厂一产品,变成了一厂多产品的模式。有朋友问了,简单工厂模式不就是一厂多产品么,没错聪明的你发现了问题。但是简单工厂模式,它只有一个唯一的厂。而抽象工厂模式,却可以根据基类的抽象工厂,派生出N多个厂,这就是其本质的区别。

        显然,这三个工厂模式的复杂度是逐渐增加的。这也是我们在进行软件设计的时候做选择的一个重要指标,针对我们具体应用场景的复杂度来选择对应的设计模式。尽量不要用一个复杂的设计模式去解决简单的问题,当然,简单的设计模式也无法很好的适配复杂的业务场景。

1.示例代码

//抽象工厂代码
#include <iostream>
using namespace std;//抽象产品A
class AbstractProductA {
public:virtual ~AbstractProductA() {}virtual void Operation() = 0;
};//具体产品A1
class ProductA1 : public AbstractProductA {
public:void Operation() {cout << "ProductA1" << endl;}
};//具体产品A2
class ProductA2 : public AbstractProductA {
public:void Operation() {cout << "ProductA2" << endl;}
};//抽象产品B
class AbstractProductB {
public:virtual ~AbstractProductB() {}virtual void Operation() = 0;
};//具体产品B1
class ProductB1 : public AbstractProductB {
public:void Operation() {cout << "ProductB1" << endl;}
};//具体产品B2
class ProductB2 : public AbstractProductB {
public:void Operation() {cout << "ProductB2" << endl;}
};//抽象工厂
class AbstractFactory {
public:virtual AbstractProductA* CreateProductA() = 0;virtual AbstractProductB* CreateProductB() = 0;virtual ~AbstractFactory() {}
};//具体工厂1:生产产品A1和B1
class ConcreteFactory1 : public AbstractFactory {
public:ProductA1* CreateProductA() {return new ProductA1();}ProductB1* CreateProductB() {return new ProductB1();}
};//具体工厂2:生产产品A2和B2
class ConcreteFactory2 : public AbstractFactory {
public:ProductA2* CreateProductA() {return new ProductA2();}ProductB2* CreateProductB() {return new ProductB2();}
};int main() {//示例代码就不判空了AbstractFactory* factory1 = new ConcreteFactory1();// 具体工厂创建对应的具体产品AbstractProductA* productA_from_factory1 = factory1->CreateProductA();  // 工厂1创建产品AAbstractProductB* productB_from_factory1 = factory1->CreateProductB();  // 工厂1创建产品BproductA_from_factory1->Operation();  // ProductA1productB_from_factory1->Operation();  // ProductB1AbstractFactory* factory2 = new ConcreteFactory2();AbstractProductA* productA_from_factory2 = factory2->CreateProductA();  // 工厂2创建产品AAbstractProductB* productB_from_factory2 = factory2->CreateProductB();  // 工厂2创建产品BproductA_from_factory2->Operation();  // ProductA2productB_from_factory2->Operation();  // ProductB2delete productA_from_factory1;delete productA_from_factory2;delete factory1;delete productB_from_factory1;delete productB_from_factory2;delete factory2;return 0;
}

2.组成结构

工厂方法模式包含的4个角色:

Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的父类。(这里需要特别说明的是,这个产品的抽象类与工厂的具体类是绑定的,也就是factory1对应一个抽象产品类product1,这是抽象工厂与工厂方法这两个模式最大的区别)
ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
Factroy(抽象工厂):在抽象工厂类中声明了工厂方法(Factory method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

3.工厂方法与抽象工厂对比

工厂方法模式:

  1. 一个抽象产品类,可以派生出多个具体产品类。
  2. 一个抽象工厂类,可以派生出多个具体工厂类。
  3. 每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:

  1. 一个抽象产品类,可以派生出多个具体产品类。
  2. 一个抽象工厂类,可以派生出多个具体工厂类。
  3. 每个具体工厂类只能创建一个具体产品类的实例。

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

4.总结

        所有的工厂模式其核心目的就是为了让对象的创建和使用分离,方便扩展。越是复杂的模式代码层次越多,可读性也变差。因此在选择设计模式的时候需要根据具体的业务场景来确定,不是越复杂的越好,也不是越简单的越好。

相关文章:

抽象工厂模式 创建性模式之五

在看这篇文章之前&#xff0c;请先看看“简单工厂模式”和“工厂方法模式”这两篇博文&#xff0c;会更有助于理解。我们现在已经知道&#xff0c;简单工厂模式就是用一个简单工厂去创建多个产品&#xff0c;工厂方法模式是每一个具体的工厂只生产一个具体的产品&#xff0c;然…...

servlet如何获取PUT和DELETE请求的参数

1. servlet为何不能获取PUT和DELETE请求的参数 Servlet的规范是POST的数据需要转给request.getParameter*()方法&#xff0c;没有规定PUT和DELETE请求也这么做 The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT or PATCH requests. T…...

【Vue.js】使用Element中的Mock.js搭建首页导航左侧菜单---【超高级教学】

一&#xff0c;Mock.js 1.1 认识Mock.js Mock.js是一个用于前端开发中生成随机数据、模拟接口响应的 JavaScript 库。模拟数据的生成器&#xff0c;用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率 总结来说&#xff0c;Element中的Mock.js是一个用于…...

从技术创新到应用实践,百度智能云发起大模型平台应用开发挑战赛!

大模型已经成为未来技术发展方向的重大变革&#xff0c;热度之下更需去虚向实&#xff0c;让技术走进产业场景。在这样的背景下&#xff0c;百度智能云于近期发起了“百度智能云千帆大模型平台应用开发挑战赛”。 挖掘大模型落地应用 千帆大模型平台应用开发挑战赛启动 在不久前…...

简单三步 用GPT-4和Gamma自动生成PPT PDF

1. 用GPT-4 生产PPT内容 我想把下面的文章做成PPT&#xff0c;请你给出详细的大纲和内容 用于谋生的知识&#xff0c;学生主要工作是学习&#xff0c;成年人的工作是养家糊口&#xff0c;这是基本的要求&#xff0c;在这之上&#xff0c;才能有更高的追求。 不要短期期望过高…...

QT设置弹窗显示屏幕中央

Qt设置每次运行弹窗显示屏幕中央 要确保Qt应用程序中的弹出窗口每次都显示在屏幕的中央&#xff0c;您可以使用以下方法&#xff1a; 使用QMessageBox的move方法手动设置窗口位置&#xff1a; #include <QApplication> #include <QMessageBox> #include <QDesk…...

正点原子嵌入式linux驱动开发——STM32MP1启动详解

STM32单片机是直接将程序下载到内部 Flash中&#xff0c;上电以后直接运行内部 Flash中的程序。 STM32MP157内部没有供用户使用的 Flash&#xff0c;系统都是存放在外部 Flash里面的&#xff0c;比如 EMMC、NAND等&#xff0c;因此 STM32MP157上电以后需要从外部 Flash加载程序…...

FPGA的数字钟带校时闹钟报时功能VHDL

名称&#xff1a;基于FPGA的数字钟具有校时闹钟报时功能 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a; 1、计时功能:这是数字钟设计的基本功能&#xff0c;每秒钟更新一次,并且能在显示屏上显示当前的时间。 2、闹钟功能:如果当前的时间与闹钟设置的时…...

分析各种表达式求值过程

目录 算术运算与赋值 编译器常用的两种优化方案 常量传播 常量折叠 加法 Debug编译选项组下编译后的汇编代码分析 Release开启02执行效率优先 减法 Release版下优化和加法一致&#xff0c;不再赘述 乘法 除法 算术结果溢出 自增和自减 关系运算与逻辑运算 JCC指…...

企业风险管理策略终极指南

企业风险管理不一定是可怕的。企业风险管理是一个模糊且难以定义的主题领域。它涵盖了企业的多种风险和程序&#xff0c;与传统的风险管理有很大不同。 那么&#xff0c;企业风险管理到底是什么&#xff1f;在本文中&#xff0c;我们将确定它是什么&#xff0c;提出两种常见的…...

OpenCV之分水岭算法(watershed)

Opencv 中 watershed函数原型&#xff1a; void watershed( InputArray image, InputOutputArray markers ); 第一个参数 image&#xff0c;必须是一个8bit 3通道彩色图像矩阵序列&#xff0c;第一个参数没什么要说的。关键是第二个参数 markers&#xff0c;Opencv官方文档的说…...

npm 命令

目录 初始化 搜索 安装 删除 更新 换源 查看 其他 补充 1.初始化 npm init #初始化一个package.json文件 npm init -y | npm init --yes 2.搜索 npm s jquery | npm search jquery 3.安装 npm install npm -g #更新到最新版本 npm i uniq | npm ins…...

【bug 记录】yolov5_C_demo 部署在 rv1126

问题1&#xff1a;opencv find 不到 在 CMakeLists 中将正确的 OpenCV库 路径添加到 CMAKE_PREFIX_PATH 变量中 set(CMAKE_PREFIX_PATH “/mnt/usr/local” ${CMAKE_PREFIX_PATH}) 问题2&#xff1a; rknn_api.h 找不到 将该文件从别处复制到项目 include 文件夹 问题3&…...

[vue-admin-template实战笔记]

1.克隆项目 git clone gitgitee.com:panjiachen/vue-admin-template.git 2.安装依赖 npm install 3.运行项目就会自动打开网页&#xff0c;并且热部署插件 npm run dev 4.查看代码 //将vue-admin-template拖入到idea中即可查看代码 1)并且发现&#xff0c;常用的东西已经集…...

unity 限制 相机移动 区域(无需碰撞检测)

限制功能原著地址&#xff1a;unity限制相机可移动区域&#xff08;box collider&#xff09;_unity限制相机移动区域_manson-liao的博客-CSDN博客 一、创建限制区域 创建一个Cube&#xff0c;Scale大小1&#xff0c;添加组件&#xff1a;BoxCollder&#xff0c;调整BoxColld…...

Hudi第二章:集成Spark

系列文章目录 Hudi第一章&#xff1a;编译安装 Hudi第二章&#xff1a;集成Spark 文章目录 系列文章目录前言一、安装Spark1、安装Spark2.安装hive 二、spark-shell1.启动命令2.插入数据3.查询数据1.转换DF2.查询 3.更新4.时间旅行5.增量查询6.指定时间点查询7.删除数据1.获取…...

springboot和vue:八、vue快速入门

vue快速入门 新建一个html文件 导入 vue.js 的 script 脚本文件 <script src"https://unpkg.com/vuenext"></script>在页面中声明一个将要被 vue 所控制的 DOM 区域&#xff0c;既MVVM中的View <div id"app">{{ message }} </div…...

docker-compose内网本地安装

1&#xff1a;通过包管理器安装 Docker Compose&#xff0c;请按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保你的系统上已经安装了 Docker。如果尚未安装 Docker&#xff0c;请根据你的操作系统使用适当的包管理器进行安装打开终端&#xff0c;并运行以下命令下载 D…...

ThreeJs的场景实现鼠标拖动旋转控制

前面一个章节中已经实现在场景中放置一个正方体&#xff0c;并添加灯光使得正方体可见。但是由于是静态的还不能证明是3D的&#xff0c;我们需要添加一些控制器&#xff0c;使得通过鼠标控制正方体可以动起来&#xff0c;实现真正的3D效果&#xff0c;由此引入OrbitControls组件…...

jdk 管理工具比对 jEnv jabba SDKMAN

jEnv、jabba、SDKMAN 这三个 JDK 管理工具进行的比对&#xff1a; jEnv&#xff1a; 地址&#xff1a;https://github.com/jenv/jenv 作者&#xff1a;Gildas Cuisinier 最后更新时间&#xff1a;2021年5月26日 开发语言&#xff1a;Shell Jabba&#xff1a; 地址&#xff1…...

华为云云耀云服务器L实例评测|部署在线图表和流程图绘制工具drawio

华为云云耀云服务器L实例评测&#xff5c;部署在线图表和流程图绘制工具drawio 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 优势及其应用场景1.3 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 drawio3.1 drawio 介绍3.2 Docker 环…...

elementui引入弹出框报错:this.$alert is not defined 解决方案

1.按需引入文件element.js 注意&#xff1a;引入Message&#xff0c;MessageBox两个组件就行&#xff0c;alert包括在MessageBox里面了。 之前我引入了Alert组件&#xff0c;发现不行 2.在vue的prototype里注册伪名字 3.组件里直接调用就行了 4.实现效果 我发现elementui调用…...

docker的组件和资源管理

Docker是一种开源的容器化平台&#xff0c;它提供了一种轻量级、可移植和可扩展的方式来打包、部署和运行应用程序。Docker的构成包括以下几个关键组件&#xff1a; Docker Engine&#xff1a;Docker Engine是Docker的核心组件&#xff0c;它负责管理容器的生命周期和资源隔离…...

SEO的优化教程(百度SEO的介绍和优化)

百度SEO关键字介绍&#xff1a; 百度SEO关键字是指用户在搜索引擎上输入的词语&#xff0c;是搜索引擎了解网站内容和相关性的重要因素。百度SEO关键字可以分为短尾词、中尾词和长尾词&#xff0c;其中长尾词更具有针对性和精准性&#xff0c;更易于获得高质量的流量。蘑菇号-…...

Tomcat以及UDP

一、Tomcat 服务端 自定义 S Tomcat服务器 S &#xff1a;Java后台开发 客户端 自定义 C 浏览器 B 认识一些常用的目录&#xff1a; bin&#xff1a;存放开始和结束的程序 conf&#xff1a;配置文件 lib&#xff1a;组成包 logs&#xff1a;输出日志 webapps&#x…...

NLP 04(GRU)

一、GRU GRU (Gated Recurrent Unit)也称门控循环单元结构,它也是传统RNN的变体,同LSTM一样能够有效捕捉长序列之间的语义关联&#xff0c; 缓解梯度消失或爆炸现象&#xff0c;同时它的结构和计算要比LSTM更简单,它的核心结构可以分为两个部分去解析: 更新门、重置门 GRU的内…...

BUUCTF reverse wp 51 - 55

findKey shift f12 找到一个flag{}字符串, 定位到关键函数, F5无效, 大概率是有花指令, 读一下汇编 这里连续push两个byte_428C54很奇怪, nop掉下面那个, 再往上找到函数入口, p设置函数入口, 再F5 LRESULT __stdcall sub_401640(HWND hWndParent, UINT Msg, WPARAM wPara…...

WebGL笔记:使用鼠标绘制多个线条应用及绘制动感线性星座

使用鼠标绘制多个线条 多个线条&#xff0c;肯定不是一笔画过的&#xff0c;而是多次画的线条既然是多线&#xff0c;那就需要有个容器来管理它们 1 &#xff09;建立容器对象 建立一个 lineBox 对象&#xff0c;作为承载多边形的容器 // lineBox.js export default class …...

nodejs+vue 汽车销售系统elementui

第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术可行性&#xff1a;技术背景 10 3.2.2经济可行性 11 3.2.3操作可行性&#xff1a; 11 3.3性能分析 11 3.4系统操作流程 12 3.4.1管理员登录流程 12 3.4.2信息添加流程 12 3.4.3信息删除流程 13 第四章 系统设计与…...

leetcode76 Minimum Window Substring

给定两个字符串s和t&#xff0c; 找到s的一个子串&#xff0c;使得t的每个字符都出现在子串中&#xff0c;求最短的子串 由于要每个字符出现&#xff0c;所以顺序其实没有关系 因此我们可以定义一个map&#xff0c;统计t中字符出现次数 然后在s中慢慢挪动滑动窗口&#xff0c;…...

站长seo/哪些店铺适合交换友情链接

css banner不拉伸现在很多网站的Banner图片都是全屏宽度的&#xff0c;这样的网站看起来显得很大气。这种Banner一般都是做一张很大的图片&#xff0c;然后在不同分辨率下都是显示图片的中间部分。实现方法如下&#xff1a;1、首先设置banner的父元素定位为相对定位&#xff0c…...

宝应123网站建设网/seo排名优化推广教程

---恢复内容开始--- ---恢复内容结束---转载于:https://www.cnblogs.com/houzhitong/archive/2013/04/03/2998172.html...

Python做网站 性能/关键词优化设计

新入手的Macbook些许不顺手&#xff0c;但不妨碍对其的喜爱度&#xff0c;如何更快速的了解MacBook使用方法呢&#xff1f;小编整理了几条非常使用的小技巧分享给大家&#xff0c;方便新人快速上手&#xff0c;提高效果~ Macbook入门技巧分享&#xff0c;上手更快效率更高你值得…...

建筑材料价格信息网/视频号排名优化帝搜软件

1 import numpy as np2 # -*- codeing:utf-8 -*-3 __author__ youfei4 5 # 隐状态6 hidden_state [sunny, rainy]7 8 # 观测序列9 obsevition [walk, shop, clean] 10 11 12 # 根据观测序列、发射概率、状态转移矩阵、发射概率 13 # 返回最佳路径 14 def compute(…...

新乐市住房和城乡建设局网站/网店营销的推广方法有哪些

1、通常打印uint8_t类型的时候&#xff0c;我们直接使用%u来打印。但是更加严谨的做法是使用%hhu来打印。详细说明参见cppreference 2、我们new之后&#xff0c;应该对指针进行判空&#xff0c;判断new是否执行成功 很多时候我们会直接这样写 Xxx *obj new Xxx();&#xff0c…...

wordpress默认管理员密码/百度搜图入口

node版本升级nvmnvmw覆盖安装第一次安装node&#xff0c;可以直接到官网下载安装程序直接安装就可以&#xff0c;但是安装后如何进行node的版本管理 发现网上也提供了node的版本管理工具&#xff1a; nvm nvm是MAC & Linux版本管理工具不适用于window nvmw nvmw是windo…...