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

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

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

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

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法

目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客&#xff1a;【写在创作纪念日】基于SpringBoot和PostG…...