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

【C++设计模式】(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

文章目录

  • (四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。工厂模式的动机在于通过一个专门的工厂类来封装对象的创建过程,以解耦对象的使用和创建,隐藏复杂的对象实例化逻辑,从而提高代码的灵活性和可维护性。通过工厂模式,客户端代码只需与工厂接口或抽象类交互,而不必直接与具体类耦合,这使得系统更易于扩展和修改。

工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式。

简单工厂模式

简单工厂模式(不属于GoF的23种设计模式):工厂类根据输入的参数决定创建哪一种产品类的实例。

#include <iostream>
#include <string>// 抽象产品类
class Product {
public:virtual void operation() = 0;virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};// 具体产品类 A
class ConcreteProductA : public Product {
public:void operation() override {std::cout << "ConcreteProductA operation." << std::endl;}
};// 具体产品类 B
class ConcreteProductB : public Product {
public:void operation() override {std::cout << "ConcreteProductB operation." << std::endl;}
};// 简单工厂类
class SimpleFactory {
public:// 静态工厂方法,根据传入的字符串类型创建具体的产品对象static Product* createProduct(const std::string& type) {if (type == "A") {return new ConcreteProductA();  // 创建并返回 ConcreteProductA 对象} else if (type == "B") {return new ConcreteProductB();  // 创建并返回 ConcreteProductB 对象} else {return nullptr;        // 如果传入的类型无效,返回空指针}}
};int main() {// 使用简单工厂创建产品 AProduct* productA = SimpleFactory::createProduct("A");if (productA) {productA->operation();delete productA;}// 使用简单工厂创建产品 BProduct* productB = SimpleFactory::createProduct("B");if (productB) {productB->operation();delete productB;}return 0;
}

以上代码通过引入一个工厂类SimpleFactory ,将产品对象AB 的创建过程封装在工厂方法中,从而实现对象创建与使用的分离。客户端只需要通过工厂来获取对象,无需了解对象的创建细节。

工厂方法模式

简单工厂违反了开闭原则(对扩展开放,对修改关闭),因为每当需要引入新产品时,都需要修改工厂类。为了避免这个问题,工厂方法模式定义一个抽象工厂类,通过继承得到可以创建不同产品的工厂。

示例

#include <iostream>
#include <string>// 抽象产品类
class Product {
public:virtual void operation() = 0;virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};// 具体产品类 A
class ConcreteProductA : public Product {
public:void operation() override {std::cout << "ConcreteProductA operation." << std::endl;}
};// 具体产品类 B
class ConcreteProductB : public Product {
public:void operation() override {std::cout << "ConcreteProductB operation." << std::endl;}
};// 抽象工厂类
class Factory {
public:virtual Product* createProduct() = 0;virtual ~Factory() {}  // 虚析构函数,确保正确释放资源
};// 具体工厂类 A,创建 ConcreteProductA
class ConcreteFactoryA : public Factory {
public:Product* createProduct() override {return new ConcreteProductA();}
};// 具体工厂类 B,创建 ConcreteProductB
class ConcreteFactoryB : public Factory {
public:Product* createProduct() override {return new ConcreteProductB();}
};int main() {// 使用具体工厂类 A 创建产品 AFactory* factoryA = new ConcreteFactoryA();Product* productA = factoryA->createProduct();productA->operation();delete productA;delete factoryA;// 使用具体工厂类 B 创建产品 BFactory* factoryB = new ConcreteFactoryB();Product* productB = factoryB->createProduct();productB->operation();delete productB;delete factoryB;return 0;
}

这段代码通过定义一个抽象工厂类Factory来声明创建产品对象的接口,具体的产品创建由具体工厂类(ConcreteFactoryAConcreteFactoryB)来实现。工厂方法模式能在不修改已有代码的情况下,通过增加新的工厂类来创建新的产品类型,实现对开闭原则的遵循。

抽象工厂模式

抽象工厂模式的主要是为了解决在不需要指定具体类的情况下,创建一组相关或依赖对象 (产品族)的需求。它通过提供一个接口来创建一系列相关或依赖对象的工厂,使得客户端可以在不指定具体实现类的情况下,创建产品族中的产品。

#include <iostream>
#include <string>// 抽象产品 A 类
class ProductA {
public:virtual void operation() = 0;virtual ~ProductA() {}  // 虚析构函数,确保正确释放资源
};// 具体产品 A1
class ConcreteProductA1 : public ProductA {
public:void operation() override {std::cout << "ConcreteProductA1 operation." << std::endl;}
};// 具体产品 A2
class ConcreteProductA2 : public ProductA {
public:void operation() override {std::cout << "ConcreteProductA2 operation." << std::endl;}
};// 抽象产品 B 类
class ProductB {
public:virtual void operation() = 0;virtual ~ProductB() {} 
};// 具体产品 B1
class ConcreteProductB1 : public ProductB {
public:void operation() override {std::cout << "ConcreteProductB1 operation." << std::endl;}
};// 具体产品 B2
class ConcreteProductB2 : public ProductB {
public:void operation() override {std::cout << "ConcreteProductB2 operation." << std::endl;}
};// 抽象工厂类
class AbstractFactory {
public:virtual ProductA* createProductA() = 0;virtual ProductB* createProductB() = 0;virtual ~AbstractFactory() {} 
};// 具体工厂 1,创建产品 A1 和 B1
class ConcreteFactory1 : public AbstractFactory {
public:ProductA* createProductA() override {return new ConcreteProductA1();}ProductB* createProductB() override {return new ConcreteProductB1();}
};// 具体工厂 2,创建产品 A2 和 B2
class ConcreteFactory2 : public AbstractFactory {
public:ProductA* createProductA() override {return new ConcreteProductA2();}ProductB* createProductB() override {return new ConcreteProductB2();}
};int main() {// 使用具体工厂 1 创建产品 A1 和 B1AbstractFactory* factory1 = new ConcreteFactory1();ProductA* productA1 = factory1->createProductA();ProductB* productB1 = factory1->createProductB();productA1->operation();productB1->operation();delete productA1;delete productB1;delete factory1;// 使用具体工厂 2 创建产品 A2 和 B2AbstractFactory* factory2 = new ConcreteFactory2();ProductA* productA2 = factory2->createProductA();ProductB* productB2 = factory2->createProductB();productA2->operation();productB2->operation();delete productA2;delete productB2;delete factory2;return 0;
}

相关文章:

【C++设计模式】(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

文章目录 &#xff08;四&#xff09;创建型模式&#xff1a;简单工厂模式&#xff0c;工厂方法模式&#xff0c;抽象工厂模式简单工厂模式工厂方法模式抽象工厂模式 &#xff08;四&#xff09;创建型模式&#xff1a;简单工厂模式&#xff0c;工厂方法模式&#xff0c;抽象工…...

浅析Golang的Context

文章目录 1. 简介2. 常见用法2.1 控制goroutine的生命周期&#xff08;cancel&#xff09;2.2 传递超时&#xff08;Timeout&#xff09;信息2.3 传递截止时间&#xff08;Deadline&#xff09;2.4 传递请求范围内的全局数据 &#xff08;value&#xff09; 3 特点3.1 上下文的…...

生日礼物C++代码

#include<bits/stdc.h> using namespace std; string s; int a,b; int main(){cout<<" 生日之地"<<\n;cout<<" 1.开始游戏"<<" 2.不想开始"<<\n;cin>>a;if(a1||a2){if(a2)cout<<…...

使用python基于DeepLabv3实现对图片进行语义分割

DeepLabv3 介绍 DeepLabv3 是一种先进的语义分割模型&#xff0c;由 Google Research 团队提出。它在 DeepLab 系列模型的基础上进行了改进&#xff0c;旨在提高图像中像素级分类的准确性。以下是 DeepLabv3 的详细介绍&#xff1a; 概述DeepLabv3 是 DeepLab 系列中的第三代…...

【漏洞复现】泛微OA E-Office do_excel.php 任意文件写入漏洞

》》》产品描述《《《 泛微0-0fice是一款标准化的协同 OA办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 》》…...

算法(食物链)

240. 食物链 题目 动物王国中有三类动物 A,B,C&#x1d434;,&#x1d435;,&#x1d436;&#xff0c;这三类动物的食物链构成了有趣的环形。 A&#x1d434; 吃 B&#x1d435;&#xff0c;B&#x1d435; 吃 C&#x1d436;&#xff0c;C&#x1d436; 吃 A&#x1d434;。…...

ubuntu20.04系统安装zookeeper简单教程

Ubuntu系统中安装和配置Zookeeper的完整指南 Apache Zookeeper是一个开源的分布式协调服务&#xff0c;广泛用于分布式应用程序中管理配置、提供命名服务、分布式同步以及组服务等。在本教程中&#xff0c;我们将详细介绍如何在Ubuntu系统中安装Zookeeper&#xff0c;并进行相关…...

.NET Core 高性能并发编程

一、高性能大并发架构设计 .NET Core 是一个高性能、可扩展的开发框架&#xff0c;可以用于构建各种类型的应用程序&#xff0c;包括高性能大并发应用程序。为了设计和开发高性能大并发 .NET Core 应用程序&#xff0c;需要考虑以下几个方面&#xff1a; 1. 异步编程 异步编程…...

B 私域模式升级:开源技术助力传统经销体系转型

一、引言 1.1 研究背景 随着市场竞争加剧&#xff0c;传统经销代理体系面临挑战。同时&#xff0c;开源技术发展迅速&#xff0c;为 B 私域升级带来新机遇。在当今数字化时代&#xff0c;企业面临着日益激烈的市场竞争。传统的经销代理体系由于管理效率低下、渠道局限、库存压…...

vue之vuex的使用及举例

Vuex是专门为Vue.js设计的集中式状态管理架构&#xff0c;它允许你将所有的组件共享状态存储在一个单独的地方&#xff0c;即“store”&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。以下是Vuex的基本使用方法&#xff1a; 一、安装Vuex 对于Vue 2项目&…...

使用 vite 快速初始化 shadcn-vue 项目

Vite 1. 创建项目 使用 vite 创建一个新的 vue 项目。 如果你正在使用 JS 模板&#xff0c;需要存在 jsconfig.json 文件才能正确运行 CLI。 # npm 6.x npm create vitelatest my-vue-app --template vue-ts# npm 7, extra double-dash is needed: npm create vitelatest m…...

微信小程序:一个小程序跳转至另一个小程序

一、微信小程序支持一个小程序跳转至另一个小程序吗&#xff1f; 支持。 1.1、目标小程序需开放被跳转&#xff1a;目标小程序需要在其 app.json 文件中配置 navigateToMiniProgramAppIdList&#xff0c;将源小程序的 AppID 加入其中。 1.2、用户授权&#xff1a;用户需要授…...

Java第二阶段---10方法带参---第二节 方法重载(Overloading)

1.概念 在同一个类中&#xff0c;方法名相同&#xff0c;参数列表不同的多个方法构造成方法重载 2.示例 public class Calculator{public int sum(int a,int b){return ab;}public int sum(int a,int b,int c){return abc;} } 3.误区 下面的方法是否属于方法重载&#xff…...

Java Web 之 Session 详解

在 JavaWeb 开发中&#xff0c;Session 就像网站的专属记忆管家&#xff0c;为每个用户保管着重要的信息和状态&#xff0c;确保用户在网站的旅程顺畅无阻。 场景一&#xff1a; 想象你去一家大型超市购物&#xff0c;推着购物车挑选商品。这个购物车就如同 Session&#xff…...

63.5 注意力提示_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录注意力提示生物学中的注意力提示查询、键和值注意力的可视化使用 show_heatmaps 显示注意力权重代码示例 代码解析结果 小结练习 注意力提示 &#x1f3f7;sec_attention-cues 感谢读者对本书的关注&#xff0c;因为读者的注意力是一种稀缺…...

vscode 的terminal 输出打印行数限制设置

修改 VSCODE 的 settings.json文件 "terminal.integrated.scrollback": 100000, {"extensions.ignoreRecommendations": true,"workbench.colorTheme": "Monokai","explorer.confirmDelete": false,"editor.fontSize…...

深入挖掘C++中的特性之一 — 继承

目录 1.继承的概念 2.举个继承的例子 3.继承基类成员访问方式的变化 1.父类成员的访问限定符对在子类中访问父类成员的影响 2.父类成员的访问限定符子类的继承方式对在两个类外访问子类中父类成员的影响 4.继承类模版&#xff08;注意事项&#xff09; 5.父类与子类间的转…...

Linux 下 poll 详解

在Linux系统编程中&#xff0c;poll 是一个强大的多路复用&#xff08;I/O 多路复用&#xff09;函数&#xff0c;用于同时监控多个文件描述符的事件&#xff0c;特别是在处理网络套接字或其他I/O设备时。相比于select&#xff0c;poll 支持监控更多的文件描述符&#xff0c;并…...

virtualbox配置为NAT模式后物理机和虚拟机互通

virtualbox配置为 NAT模式后&#xff0c;虚拟机分配到的 IP地址一般是 10.xx网段的&#xff0c;虚拟机可以通过网络地址转换访问物理机所在的网络&#xff0c;但若不做任何配置&#xff0c;则物理机无法直接访问虚拟机。 virtualbox在提供 NAT配置模式时&#xff0c;也提供了端…...

工程机械车辆挖掘机自卸卡车轮式装载机检测数据集VOC+YOLO格式2644张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2644 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注…...

万用表档位介绍与测量

万用表档位介绍与测量一&#xff1a;万用表档位介绍二&#xff1a;表笔的连接三&#xff1a;电阻测量&#xff08;Ω&#xff09;四&#xff1a;电流测量注意事项&#xff1a;1、测电流一定是串联&#xff0c;绝对不能直接把表笔搭在电源两极&#xff01;一搭就烧表、炸保险。2…...

使用Taotoken后API调用稳定性与延迟的实际体验观察

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Taotoken后API调用稳定性与延迟的实际体验观察 在最近一个为期一周的后端服务开发项目中&#xff0c;我们将原本直接调用多个厂…...

UMA Unity角色系统深度解析:运行时人体编译器架构与跨平台实践

1. 为什么UMA不是“装上就能用”的Avatar系统——从三个典型失败案例说起我第一次在项目里引入Unity Multipurpose Avatar&#xff08;UMA&#xff09;时&#xff0c;信心满满地拖进Package Manager&#xff0c;点完Import&#xff0c;打开Demo场景&#xff0c;结果角色模型直接…...

Wannakey终极指南:免费恢复WannaCry加密文件的专业内存密钥恢复工具

Wannakey终极指南&#xff1a;免费恢复WannaCry加密文件的专业内存密钥恢复工具 【免费下载链接】wannakey Wannacry in-memory key recovery 项目地址: https://gitcode.com/gh_mirrors/wa/wannakey Wannakey是一款专为恢复WannaCry勒索软件加密文件而设计的免费开源工…...

5步彻底解决显卡驱动问题:Display Driver Uninstaller完整指南

5步彻底解决显卡驱动问题&#xff1a;Display Driver Uninstaller完整指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-unin…...

3个企业级验证码识别架构设计:DdddOcr技术选型与性能优化策略

3个企业级验证码识别架构设计&#xff1a;DdddOcr技术选型与性能优化策略 【免费下载链接】ddddocr 带带弟弟 通用验证码识别OCR pypi版 项目地址: https://gitcode.com/gh_mirrors/dd/ddddocr 引言&#xff1a;验证码识别在企业自动化系统中的战略价值 在当今数字化时…...

如何快速掌握智能电源管理:macOS用户的完整配置指南

如何快速掌握智能电源管理&#xff1a;macOS用户的完整配置指南 【免费下载链接】SleeperX MacBook prevent idle/lid sleep! Hackintosh sleep on low battery capacity. 项目地址: https://gitcode.com/gh_mirrors/sl/SleeperX SleeperX是一款专为macOS用户设计的开源…...

3分钟掌握Windows安卓应用安装:APK Installer终极指南

3分钟掌握Windows安卓应用安装&#xff1a;APK Installer终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾想过在Windows电脑上直接运行安卓应用&#…...

Unity 2019格斗游戏开发:帧同步、输入缓冲与Hitbox/Hurtbox实现

1. 为什么2019版Unity仍是横板格斗开发的“黄金锚点”我带过三届游戏开发训练营&#xff0c;每次开课前都会问学员&#xff1a;“你最想用哪个版本做格斗游戏&#xff1f;”——超过七成的人脱口而出“最新版”。但当我把他们拉进一个用Unity 2019.4.40f1跑通的《街霸》风格连招…...

3个步骤:彻底释放华硕笔记本性能的终极指南

3个步骤&#xff1a;彻底释放华硕笔记本性能的终极指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Expertbook, …...