C++设计模式|创建型 2.工厂模式

1.简单工厂思想

简单工厂模式不属于23种设计模式之⼀,更多的是⼀种编程习惯。它的核心思想是将产品的创建过程封装在⼀个⼯⼚类中,把创建对象的流程集中在这个⼯⼚类⾥⾯。卡码网将其结构描述为下图所示的情况:

简单⼯⼚模式包括三个主要⻆⾊,⼯⼚类、抽象产品类、具体产品类。它们的职责如下:

  • ⼯⼚类:负责创建产品,根据传递的不同参数创建不同的产品示例。
  • 抽象产品类:由工厂类提供的接口,⽐如上图中的 Shape 接⼝,描述产品的通⽤⾏为。
  • 具体产品类:实现抽象产品接⼝或继承抽象产品类,⽐如上⾯的 Circle 类和 Square 类,具体产品通过简单⼯⼚类的 if-else 逻辑来实例化。

 简单工厂的优点是简化了客户端的操作,客户端可以调用工厂方法来获取具体产品,而无需直接与具体产品类交互,降低了耦合,但是有一个很大的问题就是不够灵活,如果需要添加新的产品,就需要修改工厂类的代码

2.什么是工厂模式?

简单工厂的思想中只有一个工厂类,用于创建所有的产品,如果需要添加新的产品,就需要修改工厂类的代码。而工厂模式引入了抽象工厂和具体工厂的概念,每个具体工厂只负责创建一个具体产品,添加新产品时只需要添加新的工厂类,支持扩展,复合开闭原则。

工厂方法模式分为以下几个角色:

  • 抽象工厂:一个接口,包含一个抽象的工厂方法,该方法用于创建产品对象
  • 具体工厂:实现抽象工厂接口,创建具体的产品。
  • 抽象产品类:定义产品的接口。
  • 具体产品类:实现抽象产品接口,是工厂创建的对象。

 工厂模式的示意图如下图所示,实际的生产系统所管理的是对应的工厂,工厂负责产品的生产。当有具体需求传入时,生产提供根据需求创建对应的工厂,这些工厂去完成需求产品的生产。在有新的产品时,只需要扩展一下产品的内容及其对应的工厂即可,原来的代码无需更改,只需要往里面添加新的模块即可,非常灵活。

 3.C++工厂模式

【设计模式专题之工厂方法模式】2.积木工厂 (kamacoder.com)icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=1076

题目描述:

小明家有两个工厂,一个用于生产圆形积木,一个用于生产方形积木,请你帮他设计一个积木工厂系统,记录积木生产的信息。

输入描述

输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示生产的次数。 

接下来的 N 行,每行输入一个字符串和一个整数,字符串表示积木的类型。积木类型分为 "Circle" 和 "Square" 两种。整数表示该积木生产的数量

输出描述

对于每个积木,输出一行字符串表示该积木的信息。

输入示例

3
Circle 1
Square 2
Circle 1

 输出示例

Circle Block
Square Block
Square Block
Circle Block

代码实现: 

先实现抽象产品类和具体产品类:

//抽象积木产品类,定义生产具体积木的接口produce()
class Block{
public://写成纯虚函数,一方面将该类变成抽象类,另一方面方便具体产品类实现多态virtual void produce() = 0;
};//具体圆形积木产品类
class CircleBlock: public Block{
public://重写父类虚函数,使用override关键字编译器会检查重写是否正确,不是非要加void produce() override {cout<<"Circle Block"<<endl;}
};//具体方形积木产品类
class SquareBlock: public Block{
public://重写父类虚函数void produce() override{cout<<"Square Block"<<endl;}
};

再实现抽象工厂类和具体工厂类,其中具体工厂类要调用具体产品的生产函数,所以工厂类写在了产品类的后面:

//抽象工厂类,提供一个抽象的接口用于创建对象。具体哪种对象还得用多态实现
class BlockFactory{
public://抽象的接口。 使用积木的基类指针作为返回值,其可以接收圆形或方形的积木对象(C++多态允许)virtual Block* createBlock() = 0;
};//具体圆形积木工厂类
class CircleBlockFactory:public BlockFactory{
public:  //重写接口函数Block* createBlock() override{return new CircleBlock();  //堆区开辟内存存放积木对象}
};//具体方形积木工厂类
class SquareBlockFactory:public BlockFactory{
public:  //重写接口函数Block* createBlock() override{return new SquareBlock();  //堆区开辟内存存放积木对象}
};

建立积木工厂系统。该系统根据输入要求去建立相对应的工厂,让该工厂去生产具体产品:

//建立积木工厂系统
class BlockManageSystem{
private://使用Block*动态数组来记录积木信息vector<Block *> blocks;
public://根据输入,建立积木生产函数。根据具体产品类型调用相对应的产品工厂void produceBlocks(BlockFactory* factory, int num){for(int i=0; i<num; i++){Block* block = factory->createBlock();this->blocks.push_back(block);block->produce();}}//由于具体积木存放在堆区,所以要使用delete进行内存释放~BlockManageSystem(){for(Block* block : blocks){delete block;}}//获取所有积木。第一个const修饰返回的引用,即使得到积木,也不能对积木进行修改。//第二个const修饰this指针,保证this指针不能对积木进行修改const vector<Block*> & getBlocks()const{return blocks;}};

总体代码:

#include<iostream>
#include<vector>
#include<string>
using namespace std;//按照工厂模式的组成,依次实现抽象产品类、具体产品类、抽象工厂类、具体工厂类//抽象积木产品类,定义生产具体积木的接口produce()
class Block{
public://写成纯虚函数,一方面将该类变成抽象类,另一方面方便具体产品类实现多态virtual void produce() = 0;
};//具体圆形积木产品类
class CircleBlock: public Block{
public://重写父类虚函数void produce() override {cout<<"Circle Block"<<endl;}
};//具体方形积木产品类
class SquareBlock: public Block{
public://重写父类虚函数,使用override关键字编译器会检查重写是否正确,不是非要加void produce() override{cout<<"Square Block"<<endl;}
};//抽象工厂类,提供一个抽象的接口用于创建对象。具体哪种对象还得用多态实现
class BlockFactory{
public://抽象的接口。 使用积木的基类指针作为返回值,其可以接收圆形或方形的积木对象(C++多态允许)virtual Block* createBlock() = 0;
};//具体圆形积木工厂类
class CircleBlockFactory:public BlockFactory{
public:  //重写接口函数Block* createBlock() override{return new CircleBlock();  //堆区开辟内存存放积木对象}
};//具体方形积木工厂类
class SquareBlockFactory:public BlockFactory{
public:  //重写接口函数Block* createBlock() override{return new SquareBlock();  //堆区开辟内存存放积木对象}
};//建立积木工厂系统
class BlockManageSystem{
private://使用Block*动态数组来记录积木信息vector<Block *> blocks;
public://根据输入,建立积木生产函数。根据具体产品类型调用相对应的产品工厂void produceBlocks(BlockFactory* factory, int num){for(int i=0; i<num; i++){Block* block = factory->createBlock();this->blocks.push_back(block);block->produce();}}//由于具体积木存放在堆区,所以要使用delete进行内存释放~BlockManageSystem(){for(Block* block : blocks){delete block;}}//获取所有积木。第一个const修饰返回的引用,即使得到积木,也不能对积木进行修改。//第二个const修饰this指针,保证this指针不能对积木进行修改const vector<Block*> & getBlocks()const{return blocks;}};int main()
{int produceNum;  //生产次数cin>>produceNum;BlockManageSystem mySystem;  //创建积木工厂系统for(int i=0; i< produceNum; i++){string blockType;int blockNum;//读取生产积木的类型和数量cin>>blockType>>blockNum;if(blockType == "Circle") {//需要使用工厂系统调用圆形积木工厂启动生产mySystem.produceBlocks(new CircleBlockFactory(),blockNum);}else if (blockType == "Square") {//需要使用工厂系统调用方形积木工厂启动生产mySystem.produceBlocks(new SquareBlockFactory(),blockNum);}}return 0;
}

4.工厂模式应用场景

工厂方法模式使得每个工厂类的职责单一每个工厂只负责创建一种产品,当创建对象涉及一系列复杂的初始化逻辑,而这些逻辑在不同的子类中可能有所不同时,可以使用工厂方法模式将这些初始化逻辑封装在子类的工厂中。

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

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

相关文章

鸿蒙端云一体化开发--调用云函数--适合小白体制

如何实现在端侧调用云函数&#xff1f; 观看前&#xff0c;友情提示&#xff1a; 不知道《如何一键创建端云一体化模板》的小白同学&#xff0c;请看&#xff1a; 鸿蒙端云一体化开发--开发云函数--适合小白体制-CSDN博客 实现方法&#xff1a; 第一步&#xff1a;添加依赖 …

3D视觉引导麻袋拆垛破包 | 某大型化工厂

客户需求 此项目为大型化工厂&#xff0c;客户现场每日有大量麻袋拆垛破包需求&#xff0c;麻袋软包由于自身易变形、码放垛型不规则、运输后松散等情况&#xff0c;无法依靠机器人示教位置完成拆垛。客户遂引入3D视觉进行自动化改造。 工作流程&#xff1a; 3D视觉对紧密贴合…

libcurl 简单使用

LibCurl是一个开源的免费的多协议数据传输开源库&#xff0c;该框架具备跨平台性&#xff0c;开源免费&#xff0c;并提供了包括HTTP、FTP、SMTP、POP3等协议的功能&#xff0c;使用libcurl可以方便地进行网络数据传输操作&#xff0c;如发送HTTP请求、下载文件、发送电子邮件等…

服务器数据恢复—V7000存储raid5数据恢复案例

服务器数据恢复环境&#xff1a; P740AIXSybaseV7000存储阵列柜&#xff0c;阵列柜上有12块SAS机械硬盘&#xff08;包括1块热备盘&#xff09;。 服务器故障&#xff1a; 管理员在日常巡检过程中发现阵列柜中有一块磁盘发生故障&#xff0c;于是更换磁盘并同步数据&#xff0…

HTTP协议安全传输教程

HTTP协议有多个版本&#xff0c;包括但不限于HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3。这些版本各自具有不同的特点和改进&#xff0c;以适应网络技术的发展和满足不同的需求。例如&#xff0c;HTTP/1.0使用文本格式传输数据&#xff0c;简单易用且兼容性好&#xff0c;…

电路笔记 : esp32pico-d4最小系统原理图

ESP32-PICO-D4 ESP32-PICO-D4是一款基于ESP32的系统级封装(SiP)模组&#xff0c;可提供完整的Wi-Fi和蓝牙功能。该模组的外观尺寸仅(7.0000.100)mm(7.0000.100)mm(0.9400.100)mm&#xff0c;整体占用的PCB面积最小&#xff0c;已集成1个4MB串行外围设备接口(SPI) flash。 ESP3…

网络层协议——IP协议

目录 IP协议 IP协议格式 分片与组装 网段划分 特殊IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 路由表生成算法 IP协议 IP协议全称为“网际互连协议&#xff08;Internet Protocol&#xff09;”&#xff0c;IP协议是TCP/IP体系中的网络层协议。 在应用层我…

外卖小程序实战-接单后小票机自动打印订单

1、导入小票机的sdk https://www.feieyun.com/api/API-JAVA.zip public static String addprinter(String snlist){//通过POST请求&#xff0c;发送打印信息到服务器RequestConfig requestConfig RequestConfig.custom() .setSocketTimeout(30000)//读取超时 .setConnectTi…

DePIN打猎之旅:AI算力作饵,道阻且长

出品&#xff5c;OKG Research 作者&#xff5c;Hedy Bi 香港Web3嘉年华已告一段落&#xff0c;然而Web3自由的脉搏还在跳动&#xff0c;并不断向其他行业渗透。和上一轮周期相比&#xff0c;本轮牛市开启的逻辑是由“原生创新叙事”转变成“主流认可&#xff0c;资金驱动”的…

C语言详解指针

目录 一、指针的概念 1.1内存与地址 例子&#xff1a; 二、变量的指针与指针变量 2.1、指针变量的定义及使用 1、指针变量的定义 2、指针变量的使用 2.2 指针变量的大小 2.3、指针-整数 2.4、void*指针 三、指针的运算 1、指针- 整数 2、指针-指针 3、指针的关系运…

一套3种风格经典的wordpress免费主题模板

wordpress免费企业主题 https://www.wpniu.com/themes/39.html 免费wordpress企业模板 https://www.wpniu.com/themes/43.html 免费wordpress企业主题 https://www.wpniu.com/themes/44.html

使用docker部署数据可视化平台Metabase

目前公司没有人力开发数据可视化看板&#xff0c;因此考虑自己搭建开源可视化平台MetaBase。在此记录下部署过程~ 一、镜像下载 docker pull metabase/metabase:latest 运行结果如下&#xff1a; 二、创建容器 docker run -dit --name matebase -p 3000:3000\ -v /home/loc…

Python编程之旅:深入探索强大的容器——列表

在Python编程的世界中&#xff0c;容器&#xff08;Containers&#xff09;是一种用于存储多个项目的数据结构。其中&#xff0c;列表&#xff08;List&#xff09;是最常用且功能强大的容器之一。无论是初学者还是资深开发者&#xff0c;掌握列表的使用方法和技巧都是提升Pyth…

四.吊打面试官系列-数据库优化-Mysql锁和事务原理

前言 本篇文章主要讲解两块内容&#xff1a;Mysql中的锁和ACID原理&#xff0c;这2个部分是面试的时候被问的蛮多的看完本篇文章之后相信你对Mysql事务会有更深层次的理解&#xff0c;如果文章对你有所帮助请记得好评 一.Mysql中的锁 1.锁的分类 在Mysql中锁也分为很多种&a…

揭秘AI精准输出:如何构建完美的AIGC提示词?

揭秘AI精准输出&#xff1a;如何构建完美的AIGC提示词&#xff1f;&#x1f916; 文章目录 揭秘AI精准输出&#xff1a;如何构建完美的AIGC提示词&#xff1f;&#x1f916;摘要引言正文&#x1f4d8; 提示词的基本概念1. 什么是提示词&#xff1f;2. 提示词的作用 &#x1f4d…

Redis安装和使用(Ubuntu系统)

本节内容包括Redis简介、安装Redis和Redis实例演示等&#xff0c;Redis在Window系统安装教程可参考Redis安装与运行_厦大数据库实验室博客 Redis是一个键值&#xff08;key-value&#xff09;存储系统&#xff0c;即键值对非关系型数据库。Redis提供了Python、Ruby、Erlang、P…

【面试八股总结】排序算法(二)

参考资料 &#xff1a;阿秀 一、堆排序 堆排序基本思想是先把数组构造成一个大顶堆(父亲节点大于其子节点)&#xff0c;然后把堆顶(数组最大值&#xff0c;数组第一个元素)和数组最后一个元素交换&#xff0c;这样就把最大值放到了数组最后边。把数组长度n-1,再进行构造堆把剩…

开源AI聊天机器人应用程序模板; WrenAI用AI从数据中获取洞见;模拟多个代理人(agents)之间语言互动的仿真系统;语音数据集标注

✨ 1: gemini-chatbot 使用Next.js构建的开源AI聊天机器人应用程序模板 Gemini-chatbot是一个使用Next.js构建的开源AI聊天机器人应用程序模板。它利用了Vercel AI SDK、Google Gemini以及Vercel KV来提供一个功能丰富、可定制的聊天体验。这个聊天机器人可以支持多种不同的A…

GitHub repository - commits - branches - releases - contributors

GitHub repository - commits - branches - releases - contributors 1. commits2. branches3. releases4. contributorsReferences 1. commits 在这里可以查看当前分支的提交历史。左侧的数字表示提交数。 2. branches 可以查看仓库的分支列表。左侧的数字表示当前拥有的分…

我们试用了6款最佳Appium替代工具,有些甚至比Appium更好

Appium是一款知名的自动化测试工具&#xff0c;用于在iOS、Android和Windows等移动平台上运行测试。就开源移动测试自动化工具而言&#xff0c;虽然替代品有限&#xff0c;但它们确实存在。我们找到了一些优秀的Appium替代品&#xff0c;它们也可以满足自动化测试要求&#xff…