《设计模式》工厂模式

news/2024/4/26 22:30:50/文章来源:https://blog.csdn.net/jokerMingge/article/details/129187908

《设计模式》工厂模式

工厂模式又分为简单工厂(Simple Factory)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)都是常用的创建型设计模式,它们的主要区别如下:

  1. 简单工厂:由一个工厂类根据传入的参数来决定创建哪一种产品类的对象。简单工厂适用于对象的创建比较简单,且客户端只需要知道传入的参数即可获取相应的对象的场景。
  2. 工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式适用于需要一组相关对象的场景,客户端不需要知道它所使用的对象的具体类型,只需要知道创建对象的接口即可。
  3. 抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。抽象工厂模式适用于需要一组相关的对象,这些对象之间有相互依赖关系,客户端不需要知道创建对象的具体实现细节,只需要知道创建对象的接口即可。

这三种工厂模式的优点及使用场景如下:

  1. 简单工厂的优点:易于实现、客户端调用方便。适用于工厂类负责创建的对象比较少的场景。
  2. 工厂方法的优点:符合开闭原则、可扩展性强。适用于需要一组相关对象,并且需要灵活地增加、替换和删除对象的场景。
  3. 抽象工厂的优点:符合开闭原则、封装性好、可扩展性强。适用于需要创建一组相互依赖、相关或不同类型的对象的场景。

综上所述,选择哪种工厂模式取决于具体的需求场景。如果只需要创建一种对象,则可以使用简单工厂;如果需要创建一组相关的对象,并且需要灵活地增加、替换和删除对象,则可以使用工厂方法;如果需要创建一组相互依赖、相关或不同类型的对象,则可以使用抽象工厂。

简单工厂

首先,定义一个抽象产品类 Product,它是由简单工厂模式负责创建的对象:

class Product {
public:virtual ~Product() {}virtual void operation() = 0;
};

接下来,定义具体产品类 ConcreteProductAConcreteProductB

class ConcreteProductA : public Product {
public:void operation() {std::cout << "ConcreteProductA::operation()" << std::endl;}
};class ConcreteProductB : public Product {
public:void operation() {std::cout << "ConcreteProductB::operation()" << std::endl;}
};

这两个类继承了抽象产品类 Product,并实现了 operation 函数。ConcreteProductAConcreteProductB 是简单工厂模式创建的具体对象。

接下来,定义一个工厂类 Factory,它负责创建具体产品的对象:

class Factory {
public:Product* create_product(int type) {switch (type) {case 0:return new ConcreteProductA();case 1:return new ConcreteProductB();default:return nullptr;}}
};

这个工厂类有一个 create_product 函数,根据传入的类型返回具体产品的对象。在这个示例中,我们使用 switch 语句根据类型选择创建哪种具体产品。

最后,我们可以在主函数中使用简单工厂模式创建具体产品的对象:

int main() {Factory factory;Product* productA = factory.create_product(0);if (productA) {productA->operation();delete productA;}Product* productB = factory.create_product(1);if (productB) {productB->operation();delete productB;}Product* productC = factory.create_product(2);if (!productC) {std::cout << "Invalid product type!" << std::endl;}return 0;
}

在主函数中,我们先创建一个工厂对象,然后分别使用它创建 ConcreteProductAConcreteProductB 的对象,并调用它们的 operation 函数进行操作。最后,我们试图使用一个不存在的类型创建产品,这时候工厂类将返回 nullptr

以上就是用 C++ 实现简单工厂模式的示例。

工厂方法

首先,定义一个抽象产品类 Product,它是由工厂方法模式负责创建的对象:

class Product {
public:virtual ~Product() {}virtual void operation() = 0;
};

接下来,定义具体产品类 ConcreteProductAConcreteProductB

class ConcreteProductA : public Product {
public:void operation() {std::cout << "ConcreteProductA::operation()" << std::endl;}
};class ConcreteProductB : public Product {
public:void operation() {std::cout << "ConcreteProductB::operation()" << std::endl;}
};

这两个类继承了抽象产品类 Product,并实现了 operation 函数。ConcreteProductAConcreteProductB 是工厂方法模式创建的具体对象。

接下来,定义一个抽象工厂类 Factory,它声明一个工厂方法 create_product,由具体工厂类负责实现这个方法:

class Factory {
public:virtual ~Factory() {}virtual Product* create_product() = 0;
};

具体工厂类继承这个抽象工厂类,并实现 create_product 方法,用于创建具体产品的对象:

class ConcreteFactoryA : public Factory {
public:Product* create_product() {return new ConcreteProductA();}
};class ConcreteFactoryB : public Factory {
public:Product* create_product() {return new ConcreteProductB();}
};

这两个类继承了抽象工厂类 Factory,并实现了 create_product 方法。ConcreteFactoryAConcreteFactoryB 是工厂方法模式创建的具体工厂。

最后,我们可以在主函数中使用工厂方法模式创建具体产品的对象:

int main() {Factory* factoryA = new ConcreteFactoryA();Product* productA = factoryA->create_product();if (productA) {productA->operation();delete productA;}delete factoryA;Factory* factoryB = new ConcreteFactoryB();Product* productB = factoryB->create_product();if (productB) {productB->operation();delete productB;}delete factoryB;return 0;
}

在主函数中,我们先创建一个 ConcreteFactoryA 对象,然后使用它创建 ConcreteProductA 的对象,并调用它的 operation 函数进行操作。然后我们创建一个 ConcreteFactoryB 对象,使用它创建 ConcreteProductB 的对象,并调用它的 operation 函数进行操作。最后,我们删除创建的对象并销毁工厂对象。

以上就是用 C++ 实现工厂方法模式的示例。

抽象工厂

首先,定义一个抽象产品类 AbstractProductAAbstractProductB,它们是由抽象工厂模式负责创建的对象:

class AbstractProductA {
public:virtual ~AbstractProductA() {}virtual void operationA() = 0;
};class AbstractProductB {
public:virtual ~AbstractProductB() {}virtual void operationB() = 0;
};

接下来,定义具体产品类 ConcreteProductA1ConcreteProductA2ConcreteProductB1ConcreteProductB2

class ConcreteProductA1 : public AbstractProductA {
public:void operationA() {std::cout << "ConcreteProductA1::operationA()" << std::endl;}
};class ConcreteProductA2 : public AbstractProductA {
public:void operationA() {std::cout << "ConcreteProductA2::operationA()" << std::endl;}
};class ConcreteProductB1 : public AbstractProductB {
public:void operationB() {std::cout << "ConcreteProductB1::operationB()" << std::endl;}
};class ConcreteProductB2 : public AbstractProductB {
public:void operationB() {std::cout << "ConcreteProductB2::operationB()" << std::endl;}
};

这四个类继承了抽象产品类 AbstractProductAAbstractProductB,并实现了 operationAoperationB 函数。ConcreteProductA1ConcreteProductA2ConcreteProductB1ConcreteProductB2 是抽象工厂模式创建的具体对象。

接下来,定义一个抽象工厂类 AbstractFactory,它声明一组工厂方法 createProductAcreateProductB,由具体工厂类负责实现这些方法:

class AbstractFactory {
public:virtual ~AbstractFactory() {}virtual AbstractProductA* createProductA() = 0;virtual AbstractProductB* createProductB() = 0;
};

具体工厂类继承这个抽象工厂类,并实现 createProductAcreateProductB 方法,用于创建具体产品的对象:

class ConcreteFactory1 : public AbstractFactory {
public:AbstractProductA* createProductA() {return new ConcreteProductA1();}AbstractProductB* createProductB() {return new ConcreteProductB1();}
};class ConcreteFactory2 : public AbstractFactory {
public:AbstractProductA* createProductA() {return new ConcreteProductA2();}AbstractProductB* createProductB() {return new ConcreteProductB2();}
};

这两个类继承了抽象工厂类 AbstractFactory,并实现了 createProductAcreateProductB 方法。ConcreteFactory1ConcreteFactory2 是抽象工厂模式创建的具体工厂。

最后,我们可以在主函数中使用抽象工厂模式创建具体产品的对象:

int main() {// 使用具体工厂1创建产品AbstractFactory* factory1 = new ConcreteFactory1();AbstractProductA* productA1 = factory1->createProductA();AbstractProductB* productB1 = factory1->createProductB();productA1->operationA();productB1->operationB();// 使用具体工厂2创建产品AbstractFactory* factory2 = new ConcreteFactory2();AbstractProductA* productA2 = factory2->createProductA();AbstractProductB* productB2 = factory2->createProductB();productA2->operationA();productB2->operationB();// 释放内存delete productA1;delete productB1;delete factory1;delete productA2;delete productB2;delete factory2;return 0;
}

运行结果如下:

ConcreteProductA1::operationA()
ConcreteProductB1::operationB()
ConcreteProductA2::operationA()
ConcreteProductB2::operationB()

这个示例实现了一个抽象工厂模式,其中抽象工厂类 AbstractFactory 声明了一组工厂方法,具体工厂类 ConcreteFactory1ConcreteFactory2 实现了这些方法,用于创建具体产品的对象。而具体产品类 ConcreteProductA1ConcreteProductA2ConcreteProductB1ConcreteProductB2 继承了抽象产品类 AbstractProductAAbstractProductB,并实现了 operationAoperationB 函数,表示具体产品的操作。

以上就是用 C++ 实现抽象工厂模式的示例。

抽象工厂模式适用于需要一次性创建一系列相关或相互依赖的对象时,它能够提供一个简单的接口,用于创建这些对象,同时保证这些对象是相互兼容的。由于该模式要求所有具体产品都必须实现相同的接口,因此它提供了更好的灵活性和可扩展性。

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

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

相关文章

注意啦!如何通过广告吸引客户直接下单?

2023年跨境电商越来越突出&#xff0c;据业内相关人士称&#xff0c;在未来几年与跨境电商相关的政策仍会继续倾斜甚至加大力度&#xff0c;因此各行各业都响应政策&#xff0c;在新政策落实之前致力于平台的转型升级&#xff0c;做新时代创新型的高质量发展&#xff0c;其实细…

Linux下的命令执行绕过技巧合集(渗透测试专用)

一、通配符* 代表『0个到无穷多个』任意字符&#xff0c;包括空字符? 代表『一定有一个』任意字符[ ] 同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd] 代表『一定有一个字符&#xff0c; 可能是 a, b, c, d 这四个任何一个』[ - ]若有减号在中括号内时&#…

(考研湖科大教书匠计算机网络)第六章应用层-第五节:文件传送协议FTP

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;概述二&#xff1a;工作原理三&#xff1a;控制连接与数据连接本节对应视频如下 【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】…

求职3个月,简历大多都石沉大海,一听是手工测试都纷纷摇头....太难了

距离被上家公司裁员已经过去了3个月了&#xff0c;3个月的求职经历真的让我痛不欲生&#xff0c;我也从中理解感叹到了很多&#xff0c;想写出来&#xff0c;告诫跟我一样的经历的人。 我今年26岁&#xff0c;大学是一所普通的大专&#xff0c;学的是机电专业&#xff0c;如何…

Python自动化测试框架封装和调用

封装与调用函数与参数化前言 面实现了参数的关联&#xff0c;那种只是记流水账的完成功能&#xff0c;不便于维护&#xff0c;也没什么可读性&#xff0c;接下来这篇可以把每一个动作写成一个函数&#xff0c;这样更方便了。参数化的思维只需记住一点&#xff1a;不要写死 登录…

类与对象(this 关键字、构造器)

目录一、面向对象二、类与对象三、对象内存图四、成员变量和局部变量区别五、this关键字六、构造器/构造方法一、面向对象 一种编程思想:也就是说我们要以何种思路&#xff0c;解决问题&#xff0c;以何种形式组织代码 当解决一个问题的时候&#xff0c;面向对象会把事物抽象成…

分享app的测试技巧

前言 今天笔者想和大家来唠唠app测试&#xff0c;现在的app有非常的多&#xff0c;这些app都是需要经过测试之后才能发布到应用市场中&#xff0c;app已经成为了我们日常生活中不可或缺的一部分了&#xff0c;但它的功能必须强大&#xff0c;才能受到消费者的重视&#xff0c;…

已解决from cryptography.hazmat.backends import default_backend导包错误

已解决Python连接FTPS抛出异常&#xff1a;CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography. The next release of cryptography (40.0) will be the last to support …

pyaudio声卡信息中hostApi是什么意思?

hostApi是声卡驱动协议&#xff0c;声卡驱动模式&#xff0c;有如下很多类。下面的类型是网上找的PortAudio的类&#xff0c;不不确定是不是python的。typedef enum PaHostApiTypeId{paInDevelopment0, /* use while developing support for a new host API */paDirectSound1,p…

深度学习之“制作自定义数据”--torch.utils.data.DataLoader重写构造方法。

深度学习之“制作自定义数据”–torch.utils.data.DataLoader重写构造方法。 前言&#xff1a; ​ 本文讲述重写torch.utils.data.DataLoader类的构造方法&#xff0c;对自定义图片制作类似MNIST数据集格式&#xff08;image, label&#xff09;&#xff0c;用于自己的Pytorc…

推荐系统从入门到入门(3)——基于MapReuduce与Spark的分布式推荐系统构建

本系列博客总结了不同框架、不同算法、不同界面的推荐系统&#xff0c;完整阅读需要大量时间&#xff08;又臭又长&#xff09;&#xff0c;建议根据目录选择需要的内容查看&#xff0c;欢迎讨论与指出问题。 目录 系列文章梗概 系列文章目录 三、MapReduce 1.MapReduce详…

【视频】海康摄像头、NVR网络协议简介

1、软硬件整体架构 2、涉及的网络协议 3、协议简介 3.1 海康私有协议 设备发现SADP:进行设备的发现、激活、修改网络参数、忘记密码等; SDK:4200、系统平台的接入前端设备,协议不对外开放,但对外提供接口库; ISAPI:Intelligent Security API(智能安全API),基于HTTP传输…

2023新的一年软件测试还值得学习吗?

最近因为疫情等各种原因&#xff0c;大厂裁员&#xff0c;失业等等频频受到关注。不解释&#xff0c;确实存在&#xff0c;各行各业都很难&#xff0c;但是&#xff0c;说软件测试行业不吃香&#xff0c;我还真不认同&#xff08;不是为培训机构说好话&#xff0c;大环境不好&a…

Odoo丨Odoo框架源码研读三:异常处理与定制化开发

Odoo丨Odoo框架源码研读三&#xff1a;异常处理与定制化开发 Odoo源码研读的第三期内容&#xff1a;异常处理与定制化开发。 *异常处理* Odoo中的Exception是对Python内置异常做了继承和封装&#xff0c;设定了自己核心的几个Exception。 而对异常的处理和Python内置异常的…

Spring 之bean的生命周期

文章目录IOCBean的生命周期运行结果实例演示实体类实例化前后置代码初始化的前后置代码application.xml总结今天我们来聊一下Spring Bean的生命周期&#xff0c;这是一个非常重要的问题&#xff0c;Spring Bean的生命周期也是比较复杂的。IOC IOC&#xff0c;控制反转概念需要…

Flutter+【三棵树】

定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴&#xff1a;Elements和RenderObjects&#xff1b;由于它们都是有着树形结构&#xff0c;所以经常会称它们为三棵树。 这三棵树分别是&#xff1a;Widget、Element、RenderObject Widget树&#xff1a;寄存烘托内容…

SigmaPlot科学绘图工具:ROC曲线分析及AUC组间差异的显著性分析

目的 初步使用SigmaPlot科学绘图工具&#xff1b;进行ROC曲线绘制并分析检验变量AUC组间差异性是否显著 软件下载及安装 SigmaPlot下载安装按照这个教程即可&#xff1a;https://www.hhkxxw.com/24799.html 快速通道&#xff1a;SigmaPlot下载链接&#xff1a;百度网盘链接…

DC220V冲击继电器RCJ-3

系列型号 RCJ-2型冲击继电器&#xff1b; RCJ-2/48VDC冲击继电器 RCJ-2/110VDC冲击继电器 RCJ-2/220VDC冲击继电器 RCJ-2/100VAC冲击继电器 RCJ-2/127VAC冲击继电器 RCJ-2/220VAC冲击继电器 RCJ-3/220VAC冲击继电器 RCJ-3型冲击继电器 RCJ-3/127VAC冲击继电器 RCJ-3/100VAC冲…

FastCGI sent in stderr: "PHP message: PHP Fatal error

服务器php7.2卸载安装7.4之后,打开网站一直无法访问,查看nginx错误日志发现一直报这个错误:2023/02/23 11:12:55 [error] 4735#0: *21 FastCGI sent in stderr: &#xff02;PHP message: PHP Fatal error: Uncaught ReflectionException: Class translator does not exist in …

Python四大主题之一【 Web】 编程框架

目前Python的网络编程框架已经多达几十个&#xff0c;逐个学习它们显然不现实。但这些框架在系统架构和运行环境中有很多共通之处&#xff0c;本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Python网络框架&#xff1a;Django、Tornado、Flask、Twisted。 …