设计模式--工厂模式
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式主要使用了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 有什么问题呢?如果有…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
