重温设计模式--工厂模式(简单、工厂、抽象)

文章目录

  • 工厂模式定义
  • 工厂模式通常可以细分为以下几种类型
    • 1、简单工厂模式(Simple Factory Pattern)
    • 2、工厂方法模式(Factory Method Pattern)
    • 3、抽象工厂模式(Abstract Factory Pattern)
  • UML 图
    • 1、简单工厂模式UML
    • 2、工厂模式UML
    • 3、抽象工厂模式UML
  • C++ 代码示例。
    • 1、简单工厂模式
      • 结构及原理
        • 简单工厂模式包含以下几个关键部分:
    • 工厂方法模式
      • 结构及原理
        • 工厂方法模式在简单工厂模式基础上做了如下改变:
  • 抽象工厂模式
    • 结构及原理
    • C++ 代码示例
  • 总结

工厂模式定义

工厂模式(Factory Pattern)属于创建型设计模式,它主要用于对象的创建过程,将对象的创建和使用分离,把对象创建的逻辑封装在工厂类中,这样当需要创建对象时,不用在客户端代码里直接通过 new 操作符等去实例化对象,而是通过调用工厂类的相应方法来获取对象。这使得代码的维护性和可扩展性更好,也提高了代码的灵活性和可复用性。

工厂模式通常可以细分为以下几种类型

1、简单工厂模式(Simple Factory Pattern)

它是工厂模式的基础,虽然严格来说不算 GoF(Gang of Four,设计模式四人组)提出的 23 种设计模式之一,但却是理解工厂模式的重要起点。简单工厂模式有一个工厂类,该工厂类根据传入的参数等条件来决定创建哪种具体产品对象。

2、工厂方法模式(Factory Method Pattern)

在简单工厂模式上进行了改进,把具体产品对象的创建方法延迟到具体的工厂子类中实现,工厂类变成抽象类,有一个抽象的创建方法,每个具体的工厂子类负责创建对应的具体产品对象,符合开闭原则(对扩展开放,对修改关闭)。

3、抽象工厂模式(Abstract Factory Pattern)

更为复杂和抽象,工厂类负责创建一系列相关的产品对象,客户端调用抽象工厂类的抽象创建方法,由具体的工厂子类来创建符合特定需求的一组相关产品,常用于创建一组有内在关联、需要统一创建的对象场景。

UML 图

1、简单工厂模式UML

在这里插入图片描述

2、工厂模式UML

在这里插入图片描述

3、抽象工厂模式UML

在这里插入图片描述

C++ 代码示例。

1、简单工厂模式

结构及原理

简单工厂模式包含以下几个关键部分:

抽象产品(Product):定义产品对象的接口,描述了产品共有的行为和属性。
具体产品(ConcreteProduct):实现抽象产品接口,代表具体的产品对象,不同的具体产品有其独特的实现逻辑。
工厂类(Factory):负责创建具体的产品对象,根据传入的条件或者参数决定实例化哪种具体产品。
C++ 代码示例

#include <iostream>
#include <string>// 抽象产品
class Product
{
public:virtual void use() = 0;virtual ~Product() {}
};// 具体产品A
class ConcreteProductA : public Product 
{
public:void use() override {std::cout << "Using ConcreteProductA" << std::endl;}
};// 具体产品B
class ConcreteProductB : public Product
{
public:void use() override{std::cout << "Using ConcreteProductB" << std::endl;}
};// 工厂类
class Factory
{
public:static Product* createProduct(const std::string& type){if (type == "A"){return new ConcreteProductA();}else if (type == "B"){return new ConcreteProductB();}return nullptr;}
};int main()
{Product* productA = Factory::createProduct("A");Product* productB = Factory::createProduct("B");if (productA){productA->use();delete productA;}if (productB){productB->use();delete productB;}char t;std::cin>>t;return 0;
}

在上述代码中:
Product 是抽象产品类,定义了 use 这个抽象方法,代表产品被使用时的操作。
ConcreteProductA 和 ConcreteProductB 是具体产品类,分别实现了 use 方法,有着各自不同的使用逻辑。
Factory 是工厂类,其 createProduct 静态方法根据传入的产品类型字符串来决定创建哪种具体产品对象,然后返回给客户端使用。在 main 函数中,通过工厂类创建了不同的产品对象并调用它们的 use 方法展示功能,最后记得释放内存,避免内存泄漏。

工厂方法模式

结构及原理

工厂方法模式在简单工厂模式基础上做了如下改变:

抽象工厂(Abstract Factory):作为工厂类的抽象,定义了抽象的创建产品的方法,具体的创建逻辑延迟到具体工厂子类中。
具体工厂(Concrete Factory):继承自抽象工厂,实现抽象的创建方法,负责创建对应的具体产品对象。
在简单工厂模式的基础上,把对象的创建分布在各个产品对应的工厂内,而不是在一个工厂内,更加符合开闭原则,简单工厂模式严格来说不符合开闭原则,因为他对修改还是开放的
C++ 代码示例

#include <iostream>
#include <string>// 抽象产品
class Product 
{
public:virtual void use() = 0;virtual ~Product() {}
};// 具体产品A
class ConcreteProductA : public Product 
{
public:void use() override{std::cout << "Using ConcreteProductA" << std::endl;}
};// 具体产品B
class ConcreteProductB : public Product 
{
public:void use() override {std::cout << "Using ConcreteProductB" << std::endl;}
};// 抽象工厂
class AbstractFactory
{
public:virtual Product* createProduct() = 0;virtual ~AbstractFactory() {}
};// 具体工厂A,负责创建产品A
class ConcreteFactoryA : public AbstractFactory
{
public:Product* createProduct() override{return new ConcreteProductA();}
};// 具体工厂B,负责创建产品B
class ConcreteFactoryB : public AbstractFactory
{
public:Product* createProduct() override{return new ConcreteProductB();}
};int main()
{AbstractFactory* factoryA = new ConcreteFactoryA();AbstractFactory* factoryB = new ConcreteFactoryB();Product* productA = factoryA->createProduct();Product* productB = factoryB->createProduct();if (productA) {productA->use();delete productA;}if (productB){productB->use();delete productB;}delete factoryA;delete factoryB;return 0;
}

在这个代码中:
AbstractFactory 抽象工厂类定义了抽象的 createProduct 方法,让具体工厂子类去实现具体的创建逻辑。
ConcreteFactoryA 和 ConcreteFactoryB 分别是负责创建不同具体产品的具体工厂类,它们重写了 createProduct 方法来实例化对应的产品。在 main 函数中,先创建具体的工厂对象,再通过工厂对象创建相应的产品对象并使用,最后按顺序释放工厂对象和产品对象的内存,保证内存管理的正确性。

抽象工厂模式

结构及原理

抽象工厂模式的核心在于创建一系列相关的产品对象,其结构特点如下:
抽象工厂(Abstract Factory):定义了创建一系列相关产品的抽象方法,例如创建产品 A、产品 B 等多个抽象方法(在更复杂场景中可能更多)。
具体工厂(Concrete Factory):实现抽象工厂接口,负责创建一组特定的相关产品对象,满足特定的业务需求组合。
抽象产品族(Abstract Product Family):包含多个抽象产品类,这些抽象产品类通常在业务上是相关联的,一起构成了产品族的抽象定义。
具体产品(Concrete Product):实现抽象产品族中的相应抽象产品类,代表具体的产品对象,不同的具体工厂创建不同组合的具体产品。

C++ 代码示例

下面以一个简单的游戏开发中创建不同主题风格的游戏角色和武器为例(比如有魔幻主题和科幻主题):

#include <iostream>
#include <string>// 抽象产品:游戏角色
class Character
{
public:virtual void show() = 0;virtual ~Character() {}
};// 抽象产品:游戏武器
class Weapon
{
public:virtual void attack() = 0;virtual ~Weapon() {}
};// 具体产品:魔幻角色
class MagicCharacter : public Character 
{
public:void show() override{std::cout << "A magic character appears." << std::endl;}
};// 具体产品:魔幻武器
class MagicWeapon : public Weapon
{
public:void attack() override {std::cout << "Magic weapon attacks with spells." << std::endl;}
};// 具体产品:科幻角色
class SciFiCharacter : public Character 
{
public:void show() override{std::cout << "A sci-fi character appears." << std::endl;}
};// 具体产品:科幻武器
class SciFiWeapon : public Weapon
{
public:void attack() override {std::cout << "Sci-fi weapon attacks with energy beams." << std::endl;}
};// 抽象工厂
class AbstractFactory
{
public:virtual Character* createCharacter() = 0;virtual Weapon* createWeapon() = 0;virtual ~AbstractFactory() {}
};// 具体工厂:魔幻主题工厂
class MagicFactory : public AbstractFactory
{
public:Character* createCharacter() override{return new MagicCharacter();}Weapon* createWeapon() override{return new MagicWeapon();}
};// 具体工厂:科幻主题工厂
class SciFiFactory : public AbstractFactory 
{
public:Character* createCharacter() override{return new SciFiCharacter();}Weapon* createWeapon() override {return new SciFiWeapon();}
};int main()
{AbstractFactory* magicFactory = new MagicFactory();AbstractFactory* sciFiFactory = new SciFiFactory();// 创建魔幻主题的角色和武器Character* magicCharacter = magicFactory->createCharacter();Weapon* magicWeapon = magicFactory->createWeapon();// 创建科幻主题的角色和武器Character* sciFiCharacter = sciFiFactory->createCharacter();Weapon* sciFiWeapon = sciFiFactory->createWeapon();if (magicCharacter) {magicCharacter->show();delete magicCharacter;}if (magicWeapon){magicWeapon->attack();delete magicWeapon;}if (sciFiCharacter){sciFiCharacter->show();delete sciFiCharacter;}if (sciFiWeapon){sciFiWeapon->attack();delete sciFiWeapon;}delete magicFactory;delete sciFiFactory;char t;std::cin>>t;return 0;
}

在这个示例中:
Character 和 Weapon 分别是抽象的游戏角色和武器产品类,定义了各自展示和攻击的抽象方法。
MagicCharacter、MagicWeapon、SciFiCharacter、SciFiWeapon 是对应的具体产品类,实现了各自的具体行为逻辑。
AbstractFactory 是抽象工厂类,定义了创建角色和武器的抽象方法。
MagicFactory 和 SciFiFactory 是具体工厂类,分别负责创建魔幻主题和科幻主题的角色和武器这一组相关产品。在 main 函数中,通过不同的具体工厂创建相应主题的产品并调用其方法展示功能,最后正确释放所有创建对象所占用的内存。

总结

简单工厂模式、工厂模式、抽象工厂模式是逐渐递进,
1、简单工厂模式是在一个工厂内生产多个产品;
2、工厂模式是一个工厂生产一个产品;
3、抽象工厂模式是一个工厂生产多个产品。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP PP 后继物料触发条件

问题&#xff1a; 物料主数据 MRP4维护了后继物料&#xff0c;该物料库存为0&#xff0c;但是做生成订单时候&#xff0c;查看BOM没有显示未后续无力啊 原因 需要在生成订单中点击可用性检查&#xff0c;才能出发对库存校验&#xff0c;才能匹配到后继物料

联通光猫怎么自己改桥接模式?

环境&#xff1a; 联通光猫 ZXHN F677V9 硬件版本号 V9.0 软件版本号 V9.0.0P1T3 问题描述&#xff1a; 联通光猫怎么自己改桥接模式 家里用的是ZXHN F677V9 光猫&#xff0c;最近又搞了个软路由&#xff0c;想改桥接模式 解决方案&#xff1a; 1.拿到最新超级密码&…

商场消防电气控制系统设计(论文+源码)

1系统的功能及方案设计 如图2.1所示为本次设计的整体框图&#xff0c;其中单片机部分采用ST89C52来负责协调各个模块&#xff1b;液晶选择LCD1602液晶屏来显示信息;温度传感器选择PT1000进行温度的检测&#xff1b;烟雾传检测选择MQ2烟雾传感器&#xff1b;CO2检测选择CCS811模…

Springboot3声明式客户端

简介 Spring Framework 6 和 Spring Boot 3 引入了一些新的特性和改进&#xff0c;以简化 HTTP API 的消费。它允许开发者通过声明式接口来定义对外部 HTTP API 的调用。其中开发者只需要定义接口和方法签名&#xff0c;而具体的实现细节由框架自动生成。 这个特性通常被称为…

信贷域——互联网金融体系

摘要 本文介绍了互联网金融的概念、特征、发展阶段和生态。互联网金融是互联网与金融结合的新兴模式&#xff0c;以大数据、云计算为基础&#xff0c;实现资金融通和支付。发展经历了技术支持、业务领域深入到金融业务领域三个阶段。互联网金融生态包括互联网支付、P2P网络借贷…

精通Redis

目录 1.NoSQL 非关系型数据库 2.Redis 3.Redis的java客户端 4.Jedis 4.1Jedis快速入门 4.2Jedis连接池及使用 5.SpringDataRedis和RedisTemplate 6.SpringDataRedis快速入门 7.RedisSerializer 1.NoSQL 非关系型数据库 基础篇-02.初始Redis-认识NoSQL_哔哩哔哩_bilib…

LabVIEW水泵性能测试系统

在现代工业应用中&#xff0c;水泵作为一种广泛使用的流体输送设备&#xff0c;其性能的可靠性对整个生产系统的稳定运行至关重要。通过LabVIEW软件配合专业硬件设备&#xff0c;设计了一套水泵性能测试系统&#xff0c;实现对各类水泵的综合性能测试与分析&#xff0c;提升水泵…

2.利用docker进行gitlab服务器迁移

一、Docker安装 安装Ubuntu 22.04.3 LTS \n \l 1、旧版本安装包清理 sudo apt-get remove docker docker-engine docker.io containerd runc当你卸载Docker时&#xff0c;存储在/var/lib/docker/中的图像、容器、卷和网络不会自动删除。如果你想从一个干净的安装开始&#x…

无人零售 4G 工业无线路由器赋能自助贩卖机高效运营

工业4G路由器为运营商赋予 “千里眼”&#xff0c;实现对贩卖机销售、库存、设备状态的远程精准监控&#xff0c;便于及时补货与维护&#xff1b;凭借强大的数据实时传输&#xff0c;助力深度洞察销售趋势、优化库存、挖掘商机&#xff1b;还能远程升级、保障交易安全、快速处理…

zabbix监控山石系列Hillstone监控模版(适用于zabbix7及以上)

监控项&#xff1a; 触发器&#xff1a; 监控数据如下&#xff1a;

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo 前言摘要引言Task 相关工作方法SDM-UniPS预处理尺度不变的空间光特征编码器像素采样变压器的非局部交互 PS-Mix数据集 实验结果训练细节评估和时间&#xff1a; 消融实验定向照明下的评估没有对…

【MySQL】7.0 入门学习(七)——MySQL基本指令:帮助、清除输入、查询等

1.0 help &#xff1f; 帮助指令&#xff0c;查询某个指令的解释、用法、说明等。详情参考博文&#xff1a; 【数据库】6.0 MySQL入门学习&#xff08;六&#xff09;——MySQL启动与停止、官方手册、文档查询 https://www.cnblogs.com/xiaofu007/p/10301005.html 2.0 在cmd命…

低代码开源项目Joget的研究——基本概念和应用

大纲 1. 基本概念1.1 Form1.1.1 Form1.1.1.1 概述1.1.1.2 主要特点和用途1.1.1.3 创建和使用 Form1.1.1.4 示例 1.1.2 Section1.1.2.1 概述1.1.2.2 主要特点和用途1.1.2.3 示例 1.1.3 Column1.1.4 Field1.1.5 示例 1.2 Datalist1.2.1 Datalist1.2.1.1 主要特点和用途1.2.1.2 创…

单机游戏《野狗子》游戏运行时提示dbghelp.dll缺失是什么原因?dbghelp.dll缺失要怎么解决?

《野狗子》游戏运行时提示dbghelp.dll缺失&#xff1a;原因与解决方案 在畅游《野狗子》这款引人入胜的游戏世界时&#xff0c;突然遭遇“dbghelp.dll缺失”的错误提示&#xff0c;无疑会给玩家的探险之旅蒙上一层阴影。作为一名深耕软件开发领域的从业者&#xff0c;我深知此…

Marscode AI辅助编程

直接使用Marscode的云服务来开发&#xff0c;也是很方便的&#xff0c;不用担心配置环境的问题&#xff0c;很适合初步学习&#xff0c;在任何设备都能开发。 番茄钟 请你基于html、tailwind css和javascript&#xff0c;帮我设计一个“番茄时钟”。要求UI简洁美观大方&#x…

使用Vue的props进行组件传递校验时出现 Extraneous non-props attributes的解决方案

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;WebStorm 目录 出现错误的情况 报错&#xff1a; 代码&#xff1a; 报错截图 原因分析 解决方案 方法一 方法二 出现错误的情况 以下是我遇到该错误时遇到的报错和代码&…

ffmpeg之显示一个yuv照片

显示YUV图片的步骤 1.初始化SDL库 目的&#xff1a;确保SDL库正确初始化&#xff0c;以便可以使用其窗口、渲染和事件处理功能。操作&#xff1a;调用 SDL_Init(SDL_INIT_VIDEO) 来初始化SDL的视频子系统。 2.创建窗口用于显示YUV图像&#xff1a; 目的&#xff1a;创建一个…

iDP3复现代码模型训练全流程(一)——train_policy.sh

iDP3 核心脚本包括三个&#xff1a;deploy_policy.sh、vis_dataset.sh、train_policy.sh&#xff0c;分别代表了部署、预处理和训练&#xff0c;分别作为对应 py 脚本的参数设置前置环节 训练环节仅需运行指令&#xff1a; # 3d policy bash scripts/train_policy.sh idp3 gr1…

链原生 Web3 AI 网络 Chainbase 推出 AVS 主网, 拓展 EigenLayer AVS 应用场景

Chainbase AVS 主网的正式上线&#xff0c;正在将 Chainbase 不同的层进行深入的串联&#xff0c;为 Chainbase 数据网络带来了验证和处理方面的应用与拓展的能力&#xff0c;并成为数据体系全面启动的新契机。 在 12 月 4 日&#xff0c;链原生的 Web3 AI 数据网络 Chainbase …

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…