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

工厂模式 - 工厂方法模式、抽象工厂模式

引言

工厂模式(Factory Pattern)是设计模式中创建型模式的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂模式主要分为两种:工厂方法模式抽象工厂模式

本文将详细介绍工厂方法模式和抽象工厂模式的概念、实现方式以及在C++中的应用。

工厂方法模式

概念

工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类。

优点

  1. 解耦:将对象的创建与使用分离,降低代码的耦合度。
  2. 扩展性好:新增产品类时,只需增加相应的工厂类,无需修改现有代码。
  3. 符合开闭原则:对扩展开放,对修改关闭。

缺点

  1. 类的数量增加:每增加一个产品类,就需要增加一个对应的工厂类,导致类的数量增加。
  2. 复杂性增加:对于简单的对象创建,使用工厂方法模式可能会增加代码的复杂性。

实现

下面是一个简单的工厂方法模式的实现示例:

#include <iostream>
#include <string>// 产品接口
class Product {
public:virtual ~Product() {}virtual void use() = 0;
};// 具体产品A
class ProductA : public Product {
public:void use() override {std::cout << "Using Product A" << std::endl;}
};// 具体产品B
class ProductB : public Product {
public:void use() override {std::cout << "Using Product B" << std::endl;}
};// 工厂接口
class Factory {
public:virtual ~Factory() {}virtual Product* createProduct() = 0;
};// 具体工厂A
class FactoryA : public Factory {
public:Product* createProduct() override {return new ProductA();}
};// 具体工厂B
class FactoryB : public Factory {
public:Product* createProduct() override {return new ProductB();}
};int main() {Factory* factoryA = new FactoryA();Product* productA = factoryA->createProduct();productA->use();Factory* factoryB = new FactoryB();Product* productB = factoryB->createProduct();productB->use();delete productA;delete productB;delete factoryA;delete factoryB;return 0;
}

应用场景

工厂方法模式适用于以下场景:

  1. 不确定对象的类型:当创建对象时,不确定具体要创建哪种类型的对象。
  2. 需要扩展:当需要扩展系统,增加新的产品类时,使用工厂方法模式可以避免修改现有代码。

抽象工厂模式

概念

抽象工厂模式(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式是工厂方法模式的扩展,它用于创建一组相关的对象。

优点

  1. 高内聚:将相关的产品族集中在一起创建,保证产品族的一致性。
  2. 解耦:将产品的创建与使用分离,降低代码的耦合度。
  3. 符合开闭原则:对扩展开放,对修改关闭。

缺点

  1. 类的数量增加:每增加一个产品族,就需要增加一个对应的工厂类,导致类的数量增加。
  2. 复杂性增加:对于简单的对象创建,使用抽象工厂模式可能会增加代码的复杂性。

实现

下面是一个简单的抽象工厂模式的实现示例:

#include <iostream>
#include <string>// 抽象产品A
class AbstractProductA {
public:virtual ~AbstractProductA() {}virtual void use() = 0;
};// 具体产品A1
class ProductA1 : public AbstractProductA {
public:void use() override {std::cout << "Using Product A1" << std::endl;}
};// 具体产品A2
class ProductA2 : public AbstractProductA {
public:void use() override {std::cout << "Using Product A2" << std::endl;}
};// 抽象产品B
class AbstractProductB {
public:virtual ~AbstractProductB() {}virtual void use() = 0;
};// 具体产品B1
class ProductB1 : public AbstractProductB {
public:void use() override {std::cout << "Using Product B1" << std::endl;}
};// 具体产品B2
class ProductB2 : public AbstractProductB {
public:void use() override {std::cout << "Using Product B2" << std::endl;}
};// 抽象工厂
class AbstractFactory {
public:virtual ~AbstractFactory() {}virtual AbstractProductA* createProductA() = 0;virtual AbstractProductB* createProductB() = 0;
};// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:AbstractProductA* createProductA() override {return new ProductA1();}AbstractProductB* createProductB() override {return new ProductB1();}
};// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:AbstractProductA* createProductA() override {return new ProductA2();}AbstractProductB* createProductB() override {return new ProductB2();}
};int main() {AbstractFactory* factory1 = new ConcreteFactory1();AbstractProductA* productA1 = factory1->createProductA();AbstractProductB* productB1 = factory1->createProductB();productA1->use();productB1->use();AbstractFactory* factory2 = new ConcreteFactory2();AbstractProductA* productA2 = factory2->createProductA();AbstractProductB* productB2 = factory2->createProductB();productA2->use();productB2->use();delete productA1;delete productB1;delete factory1;delete productA2;delete productB2;delete factory2;return 0;
}

应用场景

抽象工厂模式适用于以下场景:

  1. 产品族:当需要创建一组相关的产品时,使用抽象工厂模式可以保证产品族的一致性。
  2. 跨平台:当需要为不同的平台创建一组相关的产品时,使用抽象工厂模式可以方便地切换平台。

总结

工厂模式是一种非常实用的设计模式,它将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂方法模式适用于创建单一产品,而抽象工厂模式适用于创建一组相关的产品。在实际开发中,根据具体需求选择合适的工厂模式,可以提高代码的可维护性和可扩展性。

希望本文能帮助你更好地理解工厂方法模式和抽象工厂模式的概念、实现方式以及应用场景。如果你有任何问题或建议,欢迎在评论区留言讨论。

相关文章:

工厂模式 - 工厂方法模式、抽象工厂模式

引言 工厂模式&#xff08;Factory Pattern&#xff09;是设计模式中创建型模式的一种&#xff0c;它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离&#xff0c;使得代码更加灵活、可扩展。工厂模式主要分为两种&#xff1a;工厂方法模式和抽象工…...

2025年已过6%

前些阵子&#xff0c;注意到一个网站的年度进度条显示今年已完成4%的进度&#xff0c;而今天是1月22日&#xff0c;再一看已过去6%。如果1个月按30天来计算&#xff0c;1个月也就占一年1/12&#xff0c;差不多在8%-9%左右。 也许你会感觉这6%过得很快&#xff0c;也许你会感觉这…...

C#,入门教程(04)——Visual Studio 2022 数据编程实例:随机数与组合

上一篇&#xff1a; C#&#xff0c;入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果https://blog.csdn.net/beijinghorn/article/details/123478581 C#&#xff0c;入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net…...

UWB高精度定位技术在智能仓储中的应用

​在智能化和数字化转型的浪潮中&#xff0c;UWB高精度定位系统逐渐成为企业优化仓储管理和生产调度的关键技术。结合RFID标签打印机和服装生产型ERP软件&#xff0c;这一技术为企业带来了全新的管理方式和效率提升。 UWB高精度定位系统的核心优势 UWB&#xff08;超宽带&…...

计算机毕业设计hadoop+spark视频推荐系统 短视频推荐系统 视频流量预测系统 短视频爬虫 视频数据分析 视频可视化 视频大数据 大数据

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

【AI编辑器】字节跳动推出AI IDE——Trae,专为中文开发者深度定制

目录 一、背景 二、核心特性 2.1 AI驱动的代码自动生成 2.2 智能问答与代码补全 2.3 多语言支持 2.4 插件与扩展 三、架构 四、下载使用 4.1 下载与安装 4.2 界面与配置 五、应用实践 5.1 快速生成代码 5.2 智能问答与调试 5.3 团队协作与代码审查 六、与Cursor…...

CSDN 博客之星 2024:默语的技术进阶与社区耕耘之旅

CSDN 博客之星 2024&#xff1a;默语的技术进阶与社区耕耘之旅 &#x1f31f; 默语&#xff0c;是一位在技术分享与社区建设中坚持深耕的博客作者。今年&#xff0c;我有幸再次入围成为 CSDN 博客之星TOP300 的一员&#xff0c;这既是对过往努力的肯定&#xff0c;也是对未来探…...

《探秘鸿蒙Next:非结构化数据处理与模型轻量化的完美适配》

在鸿蒙Next的人工智能应用场景中&#xff0c;处理非结构化数据并使其适配模型轻量化需求是一项关键且具有挑战性的任务。以下是一些有效的方法和策略。 数据预处理 数据清洗&#xff1a;非结构化数据中往往存在噪声、重复和错误数据。对于文本数据&#xff0c;要去除乱码、特殊…...

async++库的使用示例

1、普通异步函数 如前面的博客介绍的&#xff0c;这个库中提供了async::spawn方法&#xff0c;这个方法通常用来启动异步函数&#xff0c;这个框架会利用线程池去完成函数&#xff0c;因此要注意数据安全。正因为将任务放到了单独的线程执行&#xff0c;并且还有调度开销&…...

springboot基于微信小程序的手机银行系统

Spring Boot基于微信小程序的手机银行系统是一种结合现代Web技术和移动应用优势的创新金融服务平台。 一、系统背景与意义 随着信息技术的快速发展和用户对便捷金融服务需求的日益增长&#xff0c;传统手机银行系统的人工管理方法已逐渐显露出效率低下、安全性低以及信息传输…...

25/1/22 算法笔记<ROS2> TF变换

TF&#xff08;Transform&#xff09; 是 ROS&#xff08;Robot Operating System&#xff09;中的一个核心功能&#xff0c;用于管理和发布坐标系之间的变换关系。TF 的主要作用是描述机器人系统中各个部分&#xff08;如传感器、执行器、底盘等&#xff09;之间的位置和姿态关…...

Android系统开发(六):从Linux到Android:模块化开发,GKI内核的硬核科普

引言&#xff1a; 今天我们聊聊Android生态中最“硬核”的话题&#xff1a;通用内核镜像&#xff08;GKI&#xff09;与内核模块接口&#xff08;KMI&#xff09;。这是内核碎片化终结者的秘密武器&#xff0c;解决了内核和供应商模块之间无尽的兼容性问题。为什么重要&#x…...

dp 凸优化

时间有点仓促&#xff0c;过几天会补。 来自 czz 学长的课&#xff0c;SMWC -> Day4 。 目录 凸函数介绍WQS二分1. P2619【国家集训队 2】Tree I2. CF739E Gosha is hunting 闵可夫斯基和1. QOJ-5421 Factories Once More2. GD 省集 tower Slope Trick1. CF713C2. ABC217H3.…...

详细介绍:Kubernetes(K8s)的技术架构(核心概念、调度和资源管理、安全性、持续集成与持续部署、网络和服务发现)

目录 前言1、K8s架构概述1.1、控制面&#xff08;Control Plane&#xff09;1.2、工作节点&#xff08;Worker Node&#xff09; 2、Kubernetes核心概念2.1、Pod2.2、ReplicaSet2.3、Deployment2.4、Service2.5、Namespace2.6、ConfigMap与Secret2.7、Persistent Volume&#x…...

[SAP ABAP] Dialog屏幕开发

Dialog屏幕开发在SAP ABAP环境中被广泛应用于创建交互式的用户界面&#xff0c;允许终端用户与应用程序进行互动 Dialog屏幕开发相关资料 [Dialog屏幕开发] 设置GUI Status 菜单/GUI Title 标题 [Dialog屏幕开发] 屏幕绘制(文本/输入框/按钮控件)...

安全测试之 SSTI 模板注入入门

文章目录 一、什么是SSTI&#xff1f;二、python 中的 Jinja2 漏洞验证三、Java 的 Thymeleaf 模版漏洞验证四、小结 一、什么是SSTI&#xff1f; SSTI&#xff08;Server-Side Template Injection&#xff09;是一种服务器端模板注入漏洞&#xff0c;它出现在使用模板引擎的W…...

滑动窗口解题模板

滑动窗口适用于固定长度的窗口问题&#xff0c;或者需要动态维护一个窗口的场景。 模板 public int slidingWindowTemplate(int[] nums, int k) { int n nums.length; int maxSum 0; // 记录最大值&#xff08;或最小值&#xff09; int windowSum 0; // 当前窗口的值 …...

SOC和SOH的含义

SOC 和 SOH 是在电池管理系统中常见的两个概念&#xff0c;通常用于描述电池的状态&#xff0c;以下是具体解释&#xff1a; SOC&#xff08;State of Charge&#xff09; 定义&#xff1a;荷电状态&#xff0c;也叫剩余电量&#xff0c;反映的是电池在一定条件下当前所剩余的…...

Genetic Prompt Search via Exploiting Language Model Probabilities

题目 利用语言模型概率的遗传提示搜索 论文地址&#xff1a;https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址&#xff1a;https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力&#xff0c;尤其是在诸如fewshot学习…...

1561. 你可以获得的最大硬币数目

class Solution:def maxCoins(self, piles: List[int]) -> int:piles.sort()res,n0,len(piles)for i in range(n//3):respiles[n-2-2*i]return res这里如果"你"想要获取最大&#xff0c;那么从最大的开始找 每隔俩算一个最大累计&#xff0c;Bob默认自己从最小那找…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

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

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

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...