当前位置: 首页 > 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设计的汉化插件。在…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...