设计模式--工厂模式
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式主要使用了C++的多态特性。将存在继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以便于子类对象的创建。
工厂模式的实现方式可分别简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
以制鞋厂为例对这三种工厂模式进行举例说明
1. 简单工厂模式
1.1 UML图
类比情形:鞋厂可以指定生产耐克、阿迪达斯和李宁牌子的鞋子。哪个鞋炒的火爆,老板就生产哪个,看形势生产。
UML图如下:

一个工厂类包含如下三要素:
- 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。
- 抽象产品类:是具体产品类的继承的父类或实现的接口。
- 具体产品类:工厂类所创建的对象就是此具体产品实例。
1.2 具体代码实现
/*** Shoes为鞋子的抽象类(基类),接口函数为Show(),用于显示鞋子广告。* NiKeShoes、AdidasShoes、LiNingShoes为具体鞋子的类,分别是耐克、阿迪达斯和李 宁鞋牌的鞋,它们都继承于Shoes抽象类。*/
#include<iostream>
using namespace std;// 鞋子抽象类
class Shoes
{
public:virtual ~Shoes() {}virtual void Show() = 0; // 纯虚函数在子类实现
};// 耐克鞋子
class NiKeShoes : public Shoes
{
public:void Show(){std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;}
};// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:void Show(){std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;}
};// 李宁鞋子
class LiNingShoes : public Shoes
{
public:void Show(){std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;}
};enum SHOES_TYPE
{NIKE,LINING,ADIDAS
};// 总鞋厂
class ShoesFactory
{
public:// 根据鞋子类型创建对应的鞋子对象Shoes *CreateShoes(SHOES_TYPE type){switch (type){case NIKE:return new NiKeShoes();break;case LINING:return new LiNingShoes();break;case ADIDAS:return new AdidasShoes();break;default:return NULL;break;}}
};int main()
{ShoesFactory shoesfactory;Shoes* ptr_nike_shoes = shoesfactory.CreateShoes(NIKE);if(ptr_nike_shoes != NULL){ptr_nike_shoes->Show();delete ptr_nike_shoes;ptr_nike_shoes = NULL;} Shoes* ptr_adidas_shoes = shoesfactory.CreateShoes(ADIDAS);if(ptr_adidas_shoes != NULL){ptr_adidas_shoes->Show();delete ptr_adidas_shoes;ptr_adidas_shoes = NULL;}Shoes* ptr_lining_shoes = shoesfactory.CreateShoes(LINING);if(ptr_lining_shoes != NULL){ptr_lining_shoes->Show();delete ptr_lining_shoes;ptr_lining_shoes = NULL;}return 0;
}
2. 工厂方法模式
2.1 UML图
**类比情形:**现各类鞋子抄的非常火热,于是为了大量生产每种类型的鞋子,则要针对不同品牌的鞋子开设独立的生产线,那么每个生产线就只能生产同类型品牌的鞋。
UML图:

工厂方法模式的结构组成:
- 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
- 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
- 抽象产品类:它是具体产品继承的父类(基类)。
- 具体产品类:具体工厂所创建的对象,就是此类。
2.2 具体代码实现
#include<iostream>
using namespace std;// 鞋子抽象类
class Shoes
{
public:virtual ~Shoes() {}virtual void Show() = 0; // 纯虚函数在子类实现
};// 耐克鞋子
class NiKeShoes : public Shoes
{
public:void Show(){std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;}
};// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:void Show(){std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;}
};// 李宁鞋子
class LiNingShoes : public Shoes
{
public:void Show(){std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;}
};// 总鞋厂实现
class ShoesFactory
{
public:virtual Shoes *CreateShoes() = 0;virtual ~ShoesFactory() {}
};// 耐克生产鞋厂
class NikeProducer : public ShoesFactory
{
public:Shoes *CreateShoes(){return new NiKeShoes();}
};// 阿迪达斯生产鞋厂
class AdidasProductor : public ShoesFactory
{
public:Shoes *CreateShoes(){return new AdidasShoes();}
};// 李宁生产鞋厂
class LiningProductor : public ShoesFactory
{
public:Shoes *CreateShoes(){return new LiNingShoes;}
};int main()
{// ================ 生产耐克流程 ==================== //// 鞋厂开设耐克生产线ShoesFactory *niKeProducer = new NikeProducer();// 耐克生产线产出球鞋Shoes *nikeShoes = niKeProducer->CreateShoes();// 耐克球鞋广告喊起nikeShoes->Show();// 释放资源delete nikeShoes;delete niKeProducer;// ================ 生产阿迪达斯流程 ==================== //// 鞋厂开设阿迪达斯生产者ShoesFactory *adidasProducer = new AdidasProductor();// 阿迪达斯生产线产出球鞋Shoes *adidasShoes = adidasProducer->CreateShoes();// 阿迪达斯球鞋广喊起adidasShoes->Show();// 释放资源delete adidasShoes;delete adidasProducer;return 0;
}
3. 抽象工程模式
场景类比:鞋厂为了扩大了业务,不仅只生产鞋子,把运动品牌的衣服也一起生产了。
3.1 UML图

3.2 具体代码实现
抽象工厂模式的结构组成(和工厂方法模式一样):
- 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
- 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
- 抽象产品类:它是具体产品继承的父类(基类)。
- 具体产品类:具体工厂所创建的对象,就是此类。
/*
Clothe和Shoes,分别为衣服和鞋子的抽象产品类。
NiKeClothe和NiKeShoes,分别是耐克衣服和耐克衣服的具体产品类。
*/
#include <iostream>
using namespace std;// 衣服基类
class Clothe{
public:virtual void Show() = 0;virtual ~Clothe(){}
};class NikeClothe : public Clothe{
public:void Show(){std::cout << "我是耐克衣服,时尚我最在行!" << std::endl;}
};// 鞋子基类
class Shoes{
public:virtual void Show() = 0;virtual ~Shoes(){};
};class NikeShoes : public Shoes{
public:void Show(){std::cout << "我是耐克球鞋,让你酷起来!" << std::endl;}
};// 总厂
class Factory{
public:virtual Shoes *CreateShoes() = 0;virtual Clothe *CreateClothe() = 0;virtual ~Factory() {}
};class NikeProducer: public Factory{
public:Shoes *CreateShoes(){return new NikeShoes();}Clothe *CreateClothe(){return new NikeClothe();}
};int main(int argc, char *argv[]){Factory *nike_producer = new NikeProducer();Clothe *nike_clothe = nike_producer->CreateClothe();Shoes *nike_shoes = nike_producer->CreateShoes();nike_clothe->Show();nike_shoes->Show();delete nike_producer;delete nike_clothe;delete nike_shoes;
}
【参考连接】
https://zhuanlan.zhihu.com/p/83535678
https://zhuanlan.zhihu.com/p/83537599(进阶版工厂类)
相关文章:
设计模式--工厂模式
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。 工厂模式主要使用了C的多态特性。将存在继承关系的类&a…...
算法笔记(十三)—— 树形DP及Morris遍历
树形DP: Question1: 以X为头结点的树,最大距离: 1. X不参与,在左子树上的最大距离 2. X不参与,在右子树上的最大距离 3. X参与,左树上最远的结点通过X到右树最远的结点 最后的结果一定是三种情况的最大…...
【Classical Network】EfficientNetV2
原文地址 原文代码 pytorch实现1 pytorch实现2 详细讲解 文章目录EfficientNet中存在的问题NAS 搜索EfficientNetV2 网络结构codeEfficientNet中存在的问题 训练图像尺寸大时,训练速度非常慢。train size 512, batch 24时,V100 out of memory在网络浅…...
索引类型FULLTEXT、NORMAL、SPATIAL、UNIQUE的区别
SQL索引的创建及使用请移步另一篇文章 (188条消息) SQL索引的创建及使用_sql索引的建立与使用_t梧桐树t的博客-CSDN博客 索引的种类 NORMAL 表示普通索引,大多数情况下都可以使用 UNIQUE 表示唯一索引,不允许重复的索引,如果该字段信息…...
稳定、可控、高可用:运维最应该加持哪些技术 buff?
如何保障开发需求高效交付,系统高峰扛得住、长期平稳,是项目组中的每位技术人必须面对的问题。 本文大纲 1、强稳定性Buff 2、风控服务实时性Buff 3、高资源利用率Buff 1.强稳定性Buff 强稳定性背后有三大挑战,其一是应对发布变更引起故障问…...
动态网站开发讲课笔记02:Java Web概述
文章目录零、本讲学习目标一、 XML基础(一)XML概述1、XML2、XML与HTML的比较(二)XML语法1、XML文档的声明2、XML元素的定义3、XML属性的定义4、XML注释的定义5、XML文件示例(三)DTD约束1、什么是XML约束2、…...
如何保护 IP 地址的隐私问题
是不是只有运营商才能查到某个人的住址信息呢?在大数据时代的今天,各种互联网应用收集了大量的数据信息,它们其实也可以根据这些信息,推断出某个人的大致地址位置。例如百度地图会一直用 App SDK 以及网页的方式记录 IP 和地址位置…...
高并发系统设计之限流
本文已收录至Github,推荐阅读 👉 Java随想录 文章目录限流算法计数器算法滑动窗口漏桶算法令牌桶算法限流算法实现Guava RateLimiter实现限流令牌预分配预热限流Nginx 限流limit_connlimit_req黑白名单限流这篇文章来讲讲限流,在高并发系统中…...
ZCMU--5286: Rose的字符串(C语言)
Description 一天Rose同学想得到一个仅由01组成的字符串S,Jack同学为了让Rose同学开心,于是打算去商店购买另一个也仅由01组成的字符串T。而商店的字符串价格由它的长度决定,比如字符串011售价3元,001011售价6元,商店…...
MAC下搭建hadoop
一:简介 Hadoop是一个用Java开发的开源框架,它允许使用简单的编程模型在跨计算机集群的分布式环境中存储和处理大数据。它的设计是从单个服务器扩展到数千个机器,每个都提供本地计算和存储。特别适合写一次,读多次的场景。 Hado…...
Python如何实现自动登录和下单的脚本,请看selenium的表演
前言 学python对selenium应该不陌生吧 Selenium 是最广泛使用的开源 Web UI(用户界面)自动化测试套件之一。Selenium 支持的语言包括C#,Java,Perl,PHP,Python 和 Ruby。目前,Selenium Web 驱动…...
华为OD机试真题Python实现【关联子串】真题+解题思路+代码(20222023)
关联子串 题目 给定两个字符串str1和str2 如果字符串str1中的字符,经过排列组合后的字符串中 只要有一个是str2的子串 则认为str1是str2的关联子串 若不是关联子串则返回-1 示例一: 输入: str1="abc",str2="efghicaibii" 输出: -1 预制条件: 输入的…...
Flutter+【三棵树】
定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴:Elements和RenderObjects;由于它们都是有着树形结构,所以经常会称它们为三棵树。 这三棵树分别是:Widget、Element、RenderObject Widget树:寄存烘托内容…...
若依系统【SpringBoot】如何集成qq邮件发送【超详细,建议收藏】
若依系统的部署博主就不在这儿阐述了,默认大家的电脑已经部署好了若依系统,这里直接开始集成邮件系统,首先我们得需要对qq邮箱进行配置;一套学不会你来打我😀; 一、开启我们的qq邮箱发送邮件的配置 1、先进…...
kettle使用--1.mysql多表关联导入mongoDB
文章目录1. 初步体验:csv 转为excelKettle概念配置mysql链接mysql 一对多关联查询结果保存到mongodb中1. 初步体验:csv 转为excel Windows环境下安装pdi-ce-8.0.0.0-28.zip ,解压后执行lib下的Spoon.bat 将csv输入拖入 双击拖进去的csv&…...
2023年CDGA考试-第10章-参考数据和主数据(含答案)
2023年CDGA考试-第10章-参考数据和主数据(含答案) 单选题 1.实现主数据中心环境的三种基本方法中不包括哪种? A.参考目录 B.注册表 C.交易中心 D.混合模式 答案 A 2.参考数据还具有很多区别于其他主数据 (例如,企业结构数据和交易结构数据)的特征。以下哪项目描述错误的…...
2023年,什么行业更有发展前景?
关于有前景有发展的行业推荐,小课今天还是推荐咱们IT互联网行业。 很多人会说现在懂电脑的那么多,这个行业都饱和了,很多学电脑的找不到工作都改行了。但事实是现在每个行各业都需要互联网,需要懂电脑的技术人才,尤其是在云计算、大数据到来…...
致盛咨询携手亚马逊云科技进一步开拓中国市场
作为医疗保健领域的咨询公司,ZS需要保证服务可靠性、敏捷性和安全性的同时,获得经济效益。亚马逊云科技丰富的云服务产品简化了ZS基础架构的搭建,为ZS节省了大量的人力与资金成本。同时,缩短了ZS扩展基础设施的周转时间࿰…...
ts之 命名空间 namespace、三斜线指令、声明文件(declare 声明ts的变量函数第三方模块等 )
目录ts之 命名空间 namespacets之 命名空间 namespacets之 三斜线指令 ( 引入其他.ts文件 )app.tsindex.tsts之 声明文件 d.ts - declare01:declare声明express第三方模块typings 为代码或者第三方模块 编写声明文件index.ts02:de…...
Day898.Join语句执行流程 -MySQL实战
Join语句执行流程 Hi,我是阿昌,今天学习记录的是关于Join语句执行流程的内容。 在实际生产中,关于 join 语句使用的问题,一般会集中在以下两类: 不让使用 join,使用 join 有什么问题呢?如果有…...
3大核心价值:Python通达信数据接口MOOTDX的完整应用指南
3大核心价值:Python通达信数据接口MOOTDX的完整应用指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx MOOTDX作为一款优秀的Python通达信数据接口封装库,为开发者提供了免…...
QQ群数据采集终极教程:5分钟掌握批量抓取技巧
QQ群数据采集终极教程:5分钟掌握批量抓取技巧 【免费下载链接】QQ-Groups-Spider QQ Groups Spider(QQ 群爬虫) 项目地址: https://gitcode.com/gh_mirrors/qq/QQ-Groups-Spider 还在为手动收集QQ群信息而烦恼吗?QQ-Groups…...
思源宋体完全免费商用指南:7种字重中文开源字体终极教程
思源宋体完全免费商用指南:7种字重中文开源字体终极教程 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 想要为你的中文设计项目找到一款既专业又完全免费的高质量字体吗&a…...
UE4插件开发实战:手把手教你为自定义资源创建独立的3D预览窗口(基于SEditorViewport)
UE4插件开发实战:打造自定义资源的3D预览视口在虚幻引擎4的编辑器扩展开发中,为自定义资源提供直观的3D预览功能是提升工具链效率的关键环节。想象一下,当技术美术师调整一把自定义武器的参数时,能够实时看到模型变化,…...
别再乱用Bool和Enum了!用UE5的Gameplay Tags重构你的角色状态机(GAS避坑指南)
别再乱用Bool和Enum了!用UE5的Gameplay Tags重构你的角色状态机(GAS避坑指南)当你的ARPG角色同时陷入眩晕、灼烧和减速状态时,传统状态机往往会暴露出致命缺陷——布尔值互相覆盖、枚举组合爆炸、条件判断嵌套成灾。而UE5的Gamepl…...
如何快速构建个人数字图书馆:番茄小说下载器终极指南
如何快速构建个人数字图书馆:番茄小说下载器终极指南 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 想要随时随地畅读番茄小说,却受限于网络连接&…...
NCM转MP3终极指南:3分钟解锁你的网易云音乐自由
NCM转MP3终极指南:3分钟解锁你的网易云音乐自由 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的歌曲换个设备就无法播放而烦恼吗?那些神秘的.ncm格式文件,只能在官方应用里…...
UE5面部动画入门:手把手教你用Blender创建Morph Target并导入引擎(附苏珊模型实操)
UE5面部动画实战:从Blender雕刻到引擎驱动的全流程解析在独立游戏开发领域,面部表情动画往往被视为高阶技能,让许多初学者望而却步。但事实上,借助UE5的Morph Target功能和Blender的基础雕刻工具,即使没有任何绑定经验…...
2026年降AI工具处理速度横评:五款主流工具一万字论文处理时长完整数据报告
2026年降AI工具处理速度横评:五款主流工具一万字论文处理时长完整数据报告 拿同一篇论文,用三款工具分别处理,记录了完整检测数据。 结论先说:嘎嘎降AI(www.aigcleaner.com)效果最稳,价格也最…...
机器学习破解等离子体模拟维度灾难:储层计算实现Vlasov方程高效闭合
1. 项目概述与核心挑战在等离子体物理和计算流体动力学领域,有一个长期困扰研究者和工程师的“幽灵”问题:闭合问题。简单来说,我们试图用计算机里有限的、离散的网格点,去描述一个本质上连续、甚至无限维度的物理世界。比如&…...
