工厂模式 - 工厂方法模式、抽象工厂模式
引言
工厂模式(Factory Pattern)是设计模式中创建型模式的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂模式主要分为两种:工厂方法模式和抽象工厂模式。
本文将详细介绍工厂方法模式和抽象工厂模式的概念、实现方式以及在C++中的应用。
工厂方法模式
概念
工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类。
优点
- 解耦:将对象的创建与使用分离,降低代码的耦合度。
- 扩展性好:新增产品类时,只需增加相应的工厂类,无需修改现有代码。
- 符合开闭原则:对扩展开放,对修改关闭。
缺点
- 类的数量增加:每增加一个产品类,就需要增加一个对应的工厂类,导致类的数量增加。
- 复杂性增加:对于简单的对象创建,使用工厂方法模式可能会增加代码的复杂性。
实现
下面是一个简单的工厂方法模式的实现示例:
#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;
}
应用场景
工厂方法模式适用于以下场景:
- 不确定对象的类型:当创建对象时,不确定具体要创建哪种类型的对象。
- 需要扩展:当需要扩展系统,增加新的产品类时,使用工厂方法模式可以避免修改现有代码。
抽象工厂模式
概念
抽象工厂模式(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式是工厂方法模式的扩展,它用于创建一组相关的对象。
优点
- 高内聚:将相关的产品族集中在一起创建,保证产品族的一致性。
- 解耦:将产品的创建与使用分离,降低代码的耦合度。
- 符合开闭原则:对扩展开放,对修改关闭。
缺点
- 类的数量增加:每增加一个产品族,就需要增加一个对应的工厂类,导致类的数量增加。
- 复杂性增加:对于简单的对象创建,使用抽象工厂模式可能会增加代码的复杂性。
实现
下面是一个简单的抽象工厂模式的实现示例:
#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;
}
应用场景
抽象工厂模式适用于以下场景:
- 产品族:当需要创建一组相关的产品时,使用抽象工厂模式可以保证产品族的一致性。
- 跨平台:当需要为不同的平台创建一组相关的产品时,使用抽象工厂模式可以方便地切换平台。
总结
工厂模式是一种非常实用的设计模式,它将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂方法模式适用于创建单一产品,而抽象工厂模式适用于创建一组相关的产品。在实际开发中,根据具体需求选择合适的工厂模式,可以提高代码的可维护性和可扩展性。
希望本文能帮助你更好地理解工厂方法模式和抽象工厂模式的概念、实现方式以及应用场景。如果你有任何问题或建议,欢迎在评论区留言讨论。
相关文章:
工厂模式 - 工厂方法模式、抽象工厂模式
引言 工厂模式(Factory Pattern)是设计模式中创建型模式的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂模式主要分为两种:工厂方法模式和抽象工…...
2025年已过6%
前些阵子,注意到一个网站的年度进度条显示今年已完成4%的进度,而今天是1月22日,再一看已过去6%。如果1个月按30天来计算,1个月也就占一年1/12,差不多在8%-9%左右。 也许你会感觉这6%过得很快,也许你会感觉这…...
C#,入门教程(04)——Visual Studio 2022 数据编程实例:随机数与组合
上一篇: C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果https://blog.csdn.net/beijinghorn/article/details/123478581 C#,入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net…...
UWB高精度定位技术在智能仓储中的应用
在智能化和数字化转型的浪潮中,UWB高精度定位系统逐渐成为企业优化仓储管理和生产调度的关键技术。结合RFID标签打印机和服装生产型ERP软件,这一技术为企业带来了全新的管理方式和效率提升。 UWB高精度定位系统的核心优势 UWB(超宽带&…...
计算机毕业设计hadoop+spark视频推荐系统 短视频推荐系统 视频流量预测系统 短视频爬虫 视频数据分析 视频可视化 视频大数据 大数据
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介: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:默语的技术进阶与社区耕耘之旅 🌟 默语,是一位在技术分享与社区建设中坚持深耕的博客作者。今年,我有幸再次入围成为 CSDN 博客之星TOP300 的一员,这既是对过往努力的肯定,也是对未来探…...
《探秘鸿蒙Next:非结构化数据处理与模型轻量化的完美适配》
在鸿蒙Next的人工智能应用场景中,处理非结构化数据并使其适配模型轻量化需求是一项关键且具有挑战性的任务。以下是一些有效的方法和策略。 数据预处理 数据清洗:非结构化数据中往往存在噪声、重复和错误数据。对于文本数据,要去除乱码、特殊…...
async++库的使用示例
1、普通异步函数 如前面的博客介绍的,这个库中提供了async::spawn方法,这个方法通常用来启动异步函数,这个框架会利用线程池去完成函数,因此要注意数据安全。正因为将任务放到了单独的线程执行,并且还有调度开销&…...
springboot基于微信小程序的手机银行系统
Spring Boot基于微信小程序的手机银行系统是一种结合现代Web技术和移动应用优势的创新金融服务平台。 一、系统背景与意义 随着信息技术的快速发展和用户对便捷金融服务需求的日益增长,传统手机银行系统的人工管理方法已逐渐显露出效率低下、安全性低以及信息传输…...
25/1/22 算法笔记<ROS2> TF变换
TF(Transform) 是 ROS(Robot Operating System)中的一个核心功能,用于管理和发布坐标系之间的变换关系。TF 的主要作用是描述机器人系统中各个部分(如传感器、执行器、底盘等)之间的位置和姿态关…...
Android系统开发(六):从Linux到Android:模块化开发,GKI内核的硬核科普
引言: 今天我们聊聊Android生态中最“硬核”的话题:通用内核镜像(GKI)与内核模块接口(KMI)。这是内核碎片化终结者的秘密武器,解决了内核和供应商模块之间无尽的兼容性问题。为什么重要&#x…...
dp 凸优化
时间有点仓促,过几天会补。 来自 czz 学长的课,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、控制面(Control Plane)1.2、工作节点(Worker Node) 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环境中被广泛应用于创建交互式的用户界面,允许终端用户与应用程序进行互动 Dialog屏幕开发相关资料 [Dialog屏幕开发] 设置GUI Status 菜单/GUI Title 标题 [Dialog屏幕开发] 屏幕绘制(文本/输入框/按钮控件)...
安全测试之 SSTI 模板注入入门
文章目录 一、什么是SSTI?二、python 中的 Jinja2 漏洞验证三、Java 的 Thymeleaf 模版漏洞验证四、小结 一、什么是SSTI? SSTI(Server-Side Template Injection)是一种服务器端模板注入漏洞,它出现在使用模板引擎的W…...
滑动窗口解题模板
滑动窗口适用于固定长度的窗口问题,或者需要动态维护一个窗口的场景。 模板 public int slidingWindowTemplate(int[] nums, int k) { int n nums.length; int maxSum 0; // 记录最大值(或最小值) int windowSum 0; // 当前窗口的值 …...
SOC和SOH的含义
SOC 和 SOH 是在电池管理系统中常见的两个概念,通常用于描述电池的状态,以下是具体解释: SOC(State of Charge) 定义:荷电状态,也叫剩余电量,反映的是电池在一定条件下当前所剩余的…...
Genetic Prompt Search via Exploiting Language Model Probabilities
题目 利用语言模型概率的遗传提示搜索 论文地址:https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址:https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力,尤其是在诸如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这里如果"你"想要获取最大,那么从最大的开始找 每隔俩算一个最大累计,Bob默认自己从最小那找…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
