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

【设计模式】工厂模式总结

工厂模式

定义一个创建对象的接口,让子类决定实例化哪个类,而对象的创建统一交由工厂去生产。

工厂模式大致可以分为三类:简单工厂模式、工厂方法模式、抽象工厂模式

简单工厂模式

简单工厂模式提供一个工厂类,根据传入的参数来创建不同类型的对象,而客户端代码无需了解对象的创建过程。

#include <iostream>// 基类,所有图形对象的父类
class Shape {
public:virtual void draw() = 0;
};// 具体的圆形类
class Circle : public Shape {
public:void draw() {std::cout << "Draw a circle" << std::endl;}
};// 具体的矩形类
class Rectangle : public Shape {
public:void draw() {std::cout << "Draw a rectangle" << std::endl;}
};// 简单工厂类
class ShapeFactory {
public:// 根据传入的参数创建不同类型的图形对象Shape* createShape(const std::string& shapeType) {if (shapeType == "circle") {return new Circle();} else if (shapeType == "rectangle") {return new Rectangle();} else {return nullptr; // 可以添加错误处理逻辑}}
};int main() {ShapeFactory factory;// 创建圆形对象Shape* circle = factory.createShape("circle");if (circle) {circle->draw();delete circle;}return 0;
}

缺点:增加新类型时需要修改工厂类,违反开闭原则。

工厂方法模式

工厂方法模式定义了一个创建对象的接口,但将具体对象的创建交给子类来实现。

#include <iostream>
#include <string>// 抽象产品类:文档
class Document {
public:virtual void open() = 0;virtual void save() = 0;
};// 具体产品类:PDF 文档
class PDFDocument : public Document {
public:void open() {std::cout << "Opening a PDF document" << std::endl;}void save() {std::cout << "Saving a PDF document" << std::endl;}
};// 具体产品类:文本文档
class TextDocument : public Document {
public:void open() {std::cout << "Opening a Text document" << std::endl;}void save() {std::cout << "Saving a Text document" << std::endl;}
};// 抽象工厂类
class DocumentFactory {
public:virtual Document* createDocument() = 0;
};// 具体工厂类:PDF 文档工厂
class PDFDocumentFactory : public DocumentFactory {
public:Document* createDocument() {return new PDFDocument();}
};// 具体工厂类:文本文档工厂
class TextDocumentFactory : public DocumentFactory {
public:Document* createDocument() {return new TextDocument();}
};int main() {DocumentFactory* factory = nullptr;Document* doc = nullptr;// 创建 PDF 文档factory = new PDFDocumentFactory();doc = factory->createDocument();doc->open();doc->save();delete doc;delete factory;// 创建文本文档factory = new TextDocumentFactory();doc = factory->createDocument();doc->open();doc->save();delete doc;delete factory;return 0;
}

优点: 扩展性好,符合了开闭原则, 新增一种产品时,只需增加改对应的产品类和对应的工厂子类即可。

缺点:每增加一种新类型,就需要增加一个对象的工厂; 相比简单工厂模式,工厂方法模式需要更多的类定义。

抽象工厂模式

抽象工厂模式允许你创建一系列相关的对象,而不指定具体的类。

#include <iostream>
#include <string>// 抽象产品类:按钮
class Button {
public:virtual void render() = 0;
};// 具体产品类:Windows按钮
class WindowsButton : public Button {
public:void render() {std::cout << "Rendering a Windows button" << std::endl;}
};// 具体产品类:Linux按钮
class LinuxButton : public Button {
public:void render() {std::cout << "Rendering a Linux button" << std::endl;}
};// 抽象产品类:窗口
class Window {
public:virtual void createButton() = 0;
};// 具体产品类:Windows窗口
class WindowsWindow : public Window {
public:void createButton() {Button* button = new WindowsButton();button->render();}
};// 具体产品类:Linux窗口
class LinuxWindow : public Window {
public:void createButton() {Button* button = new LinuxButton();button->render();}
};// 抽象工厂类
class GUIFactory {
public:virtual Window* createWindow() = 0;
};// 具体工厂类:Windows工厂
class WindowsGUIFactory : public GUIFactory {
public:Window* createWindow() {return new WindowsWindow();}
};// 具体工厂类:Linux工厂
class LinuxGUIFactory : public GUIFactory {
public:Window* createWindow() {return new LinuxWindow();}
};int main() {GUIFactory* factory = nullptr;Window* window = nullptr;// 创建Windows风格的窗口和按钮factory = new WindowsGUIFactory();window = factory->createWindow();delete factory;// 创建Linux风格的窗口和按钮factory = new LinuxGUIFactory();window = factory->createWindow();delete factory;return 0;
}

优点: 工厂抽象类创建了多个类型的产品,当有需求时,可以创建相关产品子类和子工厂类来获取。

缺点: 需要在抽象工厂类中提前确定可能需要的产品种类,以满足不同型号的多种产品的需求;如果我们需要的产品种类并没有在抽象工厂类中提前确定,则需要修改抽象工厂类了,以及所有的工厂子类。

相关文章:

【设计模式】工厂模式总结

工厂模式 定义一个创建对象的接口&#xff0c;让子类决定实例化哪个类&#xff0c;而对象的创建统一交由工厂去生产。 工厂模式大致可以分为三类&#xff1a;简单工厂模式、工厂方法模式、抽象工厂模式。 简单工厂模式 简单工厂模式提供一个工厂类&#xff0c;根据传入的参…...

网络安全管理员高级工理论题库(持续更新中)

一. 单选题&#xff08;共16题&#xff09; 1.【单选题】职业是由于社会分工和生产内部的&#xff08;&#xff09;而形成的具有特定专业和专门职责的工作。 A、劳动分工 B、智力分工 C、生产分工 D、社会分工 正确答案&#xff1a;A 2.【单选题】职业是在人类社会出现分工之后…...

RestTemplate配置和使用

在项目中&#xff0c;如果要调用第三方的http服务&#xff0c;就需要发起http请求&#xff0c;常用的请求方式&#xff1a;第一种&#xff0c;使用java原生发起http请求&#xff0c;这种方式不需要引入第三方库&#xff0c;但是连接不可复用&#xff0c;如果要实现连接复用&…...

【Hadoop】YARN容量调度器详解

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&am…...

20个Python实用小技巧!来自十年老程序员的推荐~

文章目录 1.用itertools排列2.单行条件表达式3. 反转字符串4. 使用 Assert 处理异常5. 对多个输入使用拆分6. 用 zip() 转置矩阵7. 资源上下文管理器8. 下划线作为分隔符9. 尝试 f 字符串格式10.用这个技巧交换整数11. 使用 lambda 代替函数12.多次打印无循环13. 将字符串解包为…...

jenkins原理篇——成员权限管理

大家好&#xff0c;我是蓝胖子&#xff0c;前面几节我讲述了jenkins的语法以及我是如何使用jenkins对测试和正式环境进行发布的。但正式环境使用jenkins还有一点很重要&#xff0c;那就是权限管理。正式环境的权限往往不能对所有人开放&#xff0c;以及要做到每次发布都是谁在操…...

13.求面积[有问题]

#include<stdio.h> #include<math.h> #include<bits/stdc.h> using namespace std;void fun(double a,b,c) {double p,c;p (abc)/2;c sqrt(p*(p-a)*(p-b)*(p-c));printf("面积是&#xff1a;%lf",c); }int main(){double a,b,c;scanf("%lf,%…...

【力扣】面试经典150题——哈希表

文章目录 383. 赎金信205. 同构字符串290. 单词规律 383. 赎金信 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符…...

Python批量导入及导出项目中所安装的类库包到.txt文件(补充)

Python批量导入及导出项目中所安装的类库包到.txt文件 生成requirements文件 建议使用&#xff0c;该方式形成文档最简洁&#xff1a; pip list --formatfreeze > requirements.txt...

2023 全栈工程师 Node.Js 服务器端 web 框架 Express.js 详细教程(更新中)

Express 框架概述 Express 是一个基于 Node.js 平台的快速、开放、极简的Web开发框架。它本身仅仅提供了 web 开发的基础功能&#xff0c;但是通过中间件的方式集成了外部插件来处理HTTP请求&#xff0c;例如 body-parser 用于解析 HTTP 请求体&#xff0c;compression 用于压…...

【Leetcode】【数据结构】【C语言】判断两个链表是否相交并返回交点地址

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode *tailAheadA;struct ListNode *tailBheadB;int count10;int count20;//分别找尾节点&#xff0c;并顺便统计节点数量&#xff1a;while(tailA){tailAtailA->next;c…...

Selenium爬取内容并存储至MySQL数据库

前面我通过一篇文章讲述了如何爬取博客摘要等信息。通常,在使用Selenium爬虫爬取数据后,需要存储在TXT文本中,但是这是很难进行数据处理和数据分析的。这篇文章主要讲述通过Selenium爬取我的个人博客信息,然后存储在数据库MySQL中,以便对数据进行分析,比如分析哪个时间段…...

蓝桥等考C++组别六级 007

第一部分&#xff1a;选择题 1、C L6 &#xff08;15分&#xff09; 计算一个正整数除以3的余数&#xff0c;以下选项正确的是&#xff08; &#xff09;。 A. int m; cin >> m; switch (m % 3) { default: cout << "remainder is 1"; break;// 余…...

集合框架:Set集合的特点、HashSet集合的底层原理、哈希表、实现去重复

Set集合的特点 Set&#xff08;集合&#xff09;是一种无序的、不重复的数据结构&#xff0c;它的特点如下&#xff1a; 1. 集合中的元素是无序的&#xff1a;Set 中的元素没有顺序&#xff0c;无法通过索引来访问。 2. 集合中的元素是唯一的&#xff1a;Set 中不允许有重复…...

【T690 之十二】基于方寸EVB2开发板(T690芯片)构建基于GMSSL的文件系统的方式

备注&#xff1a; 1&#xff0c;假设您已对方寸微电子的T690系列芯片的使用方式都有了一定的了解&#xff0c;然后需要构建基于GMSSL的文件系统&#xff0c;此文才对您有意义&#xff1b; 2&#xff0c;若您对方寸微电子的T690芯片不了解&#xff0c;但想进一步了解它&#xff…...

使用Selenium发邮件附件

发邮件可以使用SMTP协议实现程序去发送&#xff0c;但附件的不能太大&#xff0c;一般不超过20M。 以下使用Selenium模拟发送邮件&#xff0c;跳过这个限制&#xff0c;网上找了很多资料&#xff0c;都没有完整实现的&#xff0c;那么自己实现一个&#xff0c;以下代码用Python…...

公共数据这座金矿,授权运营为何是赋能的关键路径?

数据要素市场化正开启下一个关键阶段。 自2014年大数据写入政府工作报告&#xff0c;到全国各地大数据交易所涌现&#xff0c;再到《数据二十条》颁布&#xff0c;中国数据要素产业探索之路已走过近十载。如今&#xff0c;国家大数据局正式成立&#xff0c;更是标志着数据要素…...

昇腾CANN 7.0 黑科技:大模型推理部署技术解密

CANN作为最接近昇腾AI系列硬件产品的一层&#xff0c;通过软硬件联合设计&#xff0c;打造出适合昇腾AI处理器的软件架构&#xff0c;充分使能和释放昇腾硬件的澎湃算力。针对大模型推理场景&#xff0c;CANN最新发布的CANN 7.0版本有机整合各内部组件&#xff0c;支持大模型的…...

OAuth 2.0

OAuth 2.0 是一种授权机制&#xff0c;允许应用程序访问第三方服务的用户数据&#xff0c;而不需要用户提供用户名和密码。其原理包括以下几个步骤&#xff1a; 应用程序向第三方服务请求授权&#xff0c;并提供自己的身份信息。 第三方服务向用户展示授权请求的具体内容和应用…...

7个设计师必备的Figma汉化插件,高效设计超简单!

Figma是一个著名的在线设计工具&#xff0c;拥有来自全球各地的超多设计师都在用&#xff0c;粉丝多多。其强大和灵活的设计功能使许多设计师都喜欢使用它。然而&#xff0c;为了进一步提高设计效率和扩展功能&#xff0c;许多开发人员开发了各种有用的Figma设计的汉化插件。在…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...