设计模式----工厂模式

工厂模式

工厂模式即建立创建对象的工厂,实现创建者和调用者分离。

  • 简单工厂模式:该模式对对象创建管理方式最为简单,因为他简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。

  • 工厂方法模式:将生成具体产品的任务分发给具体的产品工厂。

  • 抽象工厂模式:通过在AbstractFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建。

简单工厂模式

简单工厂模式UML图
下面通过手机生产的过程进行理解:

#include <stdio.h>typedef enum productType
{xiaomi,iphone,huawei
}PRODUCTTYPE;
class Phone
{
public:virtual void MakePhone() = 0;
};
class MI : public Phone
{
public:void MakePhone(){printf("make xiaomi phone\n");}
};
class IPHONE : public Phone
{
public:void MakePhone(){printf("make iphone phone\n");}
};
class HUAWEI : public Phone
{
public:void MakePhone(){printf("make huawei phone\n");}
};
class SimpleFactory
{
public:Phone *createPhone(PRODUCTTYPE type){switch (type){case xiaomi:return new MI();case iphone:return new IPHONE();case huawei:return new HUAWEI();default:return NULL;}}
};
int main()
{SimpleFactory *factory = new  SimpleFactory();Phone *phone1 =  factory->createPhone(huawei);if (phone1 != NULL)phone1->MakePhone();Phone *phone2 =  factory->createPhone(xiaomi);if (phone2 != NULL)phone2->MakePhone();Phone *phone3 =  factory->createPhone(iphone);if (phone3 != NULL)phone3->MakePhone();delete phone1;phone1 = NULL;delete phone2;phone2 = NULL;delete phone3;phone3 = NULL;return 0;
}

工厂方法模式

工厂方法模式UML图
简单工厂模式例子中,已经可以生产xiaomi,iphone和huawei三类产品。此时需要添加oppo产品。那么此时需要在产品枚举中添加新的产品类型,然后修改factory中的switch语句。这种改动量比较大,大工程中易产生错误,这种扩展方式是很糟糕的。并且由于对原始代码进行了修改,那么原来的测试工作就无效了,需要进行新的全覆盖测试。

工厂方法模式是在简单工厂模式的基础上,对工厂添加了一个抽象层。将工厂共同的动作抽象出来,而具体的实现由子类本身去实现,让子类决定生产什么样的产品。

应用场景

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。核心工厂不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

1、设计初期,就考虑到产品在后期进行扩展的情况下,可以使用工厂方法模式。
2、产品结构复杂的请情况下,可以使用工厂方法模式。

设计模式在详细设计时就需要进行定夺,需要权衡很多方面的因素,不能为了使用而使用。

#include <stdio.h>class Phone
{
public:virtual void MakePhone() = 0;
};
class MI : public Phone
{
public:void MakePhone(){printf("xiaomi phone\n");}
};
class HUAWEI : public Phone
{
public:void MakePhone(){printf("huawei phone\n");}
};
class Factory
{
public:virtual Phone *CreatePhone() = 0;
};
class MIFactory : public Factory
{
public:Phone *CreatePhone(){return new MI();}
};
class HUAWEIFactory : public Factory
{
public:Phone *CreatePhone(){return new HUAWEI();}
};
void main()
{Factory *MIfactory = new MIFactory();Phone *mi = MIfactory->CreatePhone();mi->MakePhone();Factory *HWfactory = new HUAWEIFactory();Phone *huawei = HWfactory->CreatePhone();huawei->MakePhone();if (MIfactory){delete MIfactory;MIfactory = NULL;}if (mi){delete mi;mi = NULL;}if (HWfactory){delete HWfactory;HWfactory = NULL;}if (huawei){delete huawei;huawei = NULL;}
}

抽象工厂模式

工厂方法模式,后期产品会越来越多,建立的工厂也会越来越多,工厂进行了增长,工厂变得凌乱而难于管理;由于工厂方法模式创建的对象都是继承于phone的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的产品时(不继承自phone),工厂方法则心有余而力不足。

举个例子方理解:

一个显示器电路板厂商,旗下的显示器电路板种类有液晶和非液晶的;这个时候厂商建造两个工厂,A工厂负责生产液晶电路板;B工厂负责生产非液晶电路板;工厂一直这样运行着。但是有一天经理发现这届生产显示器的其他部分也能挣钱,所以,决定在建立两个厂C和D,C负责生产液晶显示其余部件;D负责生产非液晶显示器的其余部件。此时,旁边的参谋提出我们只需要在原有的A和B厂添加一条负责液晶和非液晶显示器其余部件的生产线。这样做只需要对原有的厂房进行扩大,而不需要增加新的厂房,一方面,方便管理;另一方面,生产液晶和非液晶显示器的技术人员对液晶显示器和液晶显示器的其他部件生产具有指导作用。
在软件的开过程中,工厂A和B就是工厂方法模式;再建立C和D,就是重复工厂方法模式,只是生产的产品不一样。这样做增加成本。在面向对象中,很注重对象的维护和管理,对象越多,就越难维护,成本也会增加。

抽象工厂模式UML图
抽象工厂模式,就好比是两个工厂方法模式的叠加。抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。在工厂factory中的每一个方法,就好比是一条生产线,而生产线实际需要生产什么养的产品,这是由factory1和factory2去决定的,这样便延迟了具体子类的实例化;同时集中化了生产线的管理,节省了资源的浪费。

使用场合:
工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构的场合,主要用于创建一组(有多个种类)相关的产品,为他们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以排上用场。

#include <stdio.h>class MI
{
public:virtual void MakePhone() = 0;
};
class RedMI : public MI
{
public:void MakePhone(){printf("redmi phone\n");}
};
class MIPro : public MI
{
public:void MakePhone(){printf("MIPro phone\n");}
};
class HUAWEI
{
public:virtual void MakePhone() = 0;
};
class Mate20 : public HUAWEI
{
public:void MakePhone(){printf("Mate20 Phone\n");}
};
class P30 : public HUAWEI
{
public:void MakePhone(){printf("P30 phone\n");}
};
class Factory
{
public:virtual MI* CreateMIPhone() = 0;virtual HUAWEI* CreateHWPhone() = 0;
};
class Factory1 : public Factory
{
public:MI* CreateMIPhone(){return new RedMI();}HUAWEI* CreateHWPhone(){return new Mate20();}
};
class Factory2 : public Factory
{
public:MI* CreateMIPhone(){return new MIPro();}HUAWEI* CreateHWPhone(){return new P30();}
};
void main()
{Factory *factoryObj1 = new Factory1();MI *mi1 = factoryObj1->CreateMIPhone();HUAWEI *hw1 = factoryObj1->CreateHWPhone();mi1->MakePhone();hw1->MakePhone();Factory *factoryObj2 = new Factory2();MI *mi2 = factoryObj2->CreateMIPhone();HUAWEI *hw2 = factoryObj2->CreateHWPhone();mi2->MakePhone();hw2->MakePhone();if (factoryObj1){delete factoryObj1;factoryObj1 = NULL;}if (factoryObj2){delete factoryObj2;factoryObj2 = NULL;}if (mi1){delete mi1;mi1 = NULL;}if (mi2){delete mi2;mi2 = NULL;}if (hw1){delete hw1;hw1 = NULL;}if (hw2){delete hw2;hw2 = NULL;}
}

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

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

相关文章

JVM对象的创建流程与内存分配

对象的创建流程与内存分配 创建流程对象内存分配方式内存分配安全问题对象内存分配流程【重要】:对象怎样才会进入老年代?重点 案例演示:对象分配过程大对象直接进入老年代02-对象内存分配的过程: 创建流程 加载 验证 解析 准备 初始化 使用 写在 对象内存分配方式 内存分配…

GPT-SoVITS-WebUI 克隆声音 macos搭建

强大的少样本语音转换与语音合成Web用户界面 macos运行参考 macos conda create -n GPTSoVits python3.9 conda activate GPTSoVits激活环境 conda activate GPTSoVits停用 conda deactivate mkdir GPTSoVits cd GPTSoVits git clone https://github.com/RVC-Boss/GPT-SoVITS…

算法项目(1)—— LSTM+CNN+四种注意力对比的股票预测

本文包含什么? 项目运行的方式(包教会)项目代码(在线运行免环境配置)不通注意力的模型指标对比一些效果图运行有问题? csdn上后台随时售后.项目说明 本项目实现了基于CNN+LSTM构建模型,然后对比不同的注意力机制预测股票走势的效果。首先看一下模型结果的对比: 模型MS…

2024年2月的TIOBE指数,go语言排名第8,JAVA趋势下降

二月头条&#xff1a;go语言进入前十 本月&#xff0c;go在TIOBE指数前10名中排名第8。这是go有史以来的最高位置。当谷歌于2009年11月推出Go时&#xff0c;它一炮而红。在那些日子里&#xff0c;谷歌所做的一切都是神奇的。在Go出现的几年前&#xff0c;谷歌发布了GMail、谷歌…

枚举类(enum)

优质博文&#xff1a;IT-BLOG-CN ​ 枚举类&#xff1a; 就是对象的实例个数是确定的&#xff08;例如&#xff1a;单例模式&#xff09;&#xff0c;也就说我们在创建枚举类的时候&#xff0c;会对构造器进行设置 一、自定义创建枚举类 为什么需要枚举类&#xff1f; 【1】…

我国无水氢氟酸产量逐渐增长 东岳集团市场占比较大

我国无水氢氟酸产量逐渐增长 东岳集团市场占比较大 无水氢氟酸是一种十分重要的化工产品&#xff0c;在常温常压下多表现为一种无色发烟液体。无水氢氟酸具有吸水性强、化学活性高、介电常数高、阻燃性能好等优点。经过多年发展&#xff0c;无水氢氟酸制备方法已经成熟&#xf…

Spring Cloud Alibaba-04-Sentinel服务容错

Lison <dreamlison163.com>, v1.0.0, 2023.09.10 Spring Cloud Alibaba-04-Sentinel服务容错 文章目录 Spring Cloud Alibaba-04-Sentinel服务容错高并发带来的问题服务雪崩效应常见容错方案Sentinel入门什么是Sentinel微服务集成Sentinel安装Sentinel控制台 实现一个接…

【前端】前端三要素之BOM

写在前面&#xff1a;本文仅包含BOM内容&#xff0c;JavaScript传送门在这里&#xff0c;DOM传送门在这里。 本文内容是假期中刷的黑马Pink老师视频&#xff08;十分感谢Pink老师&#xff09;&#xff0c;原文保存在个人的GitLab中&#xff0c;如果需要写的网页内容信息等可以评…

QT设置窗口随窗体变化(窗口文本框随窗体的伸缩)

目录 1.建立新窗口2.最终效果 1.建立新窗口 1&#xff09;在窗体中创建一个 textBrowser&#xff0c;记录坐标及宽高 X-100 Y-130 宽-571 高-281&#xff0c;窗体宽高800*600&#xff1b; 2&#xff09;在.h头文件中插入void resizeEvent(QResizeEvent *event) override;函数 …

挑战!贪吃蛇小游戏的实现(3)

经过&#xff08;1&#xff09;&#xff08;2&#xff09;两篇文章的介绍&#xff0c;相信大家对该游戏的实现已经有了具体的思路&#xff0c;废话不多说&#xff0c;让我们开始实现相关的代码吧&#xff01; 1.游戏主逻辑 void test() {int ch 0;srand((unsigned int)time(NU…

【Unity3D】ASE制作天空盒

找到官方shader并分析 下载对应资源包找到\DefaultResourcesExtra\Skybox-Cubed.shader找到\CGIncludes\UnityCG.cginc观察变量, 观察tag, 观察代码 需要注意的内容 ASE要处理的内容 核心修改 添加一个Custom Expression节点 code内容为: return DecodeHDR(In0, In1);outp…

在Win系统部署WampServer并实现公网访问本地服务【内网穿透】

目录 推荐 前言 1.WampServer下载安装 2.WampServer启动 3.安装cpolar内网穿透 3.1 注册账号 3.2 下载cpolar客户端 3.3 登录cpolar web ui管理界面 3.4 创建公网地址 4.固定公网地址访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…

企业资产|企业资产管理系统|基于springboot企业资产管理系统设计与实现(源码+数据库+文档)

企业资产管理系统目录 目录 基于springboot企业资产管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、用户审核管理 3、资产分类管理 4、资产信息管理 5、资产信息添加 6、资产借出统计 7、资产归还审核 8、资产维修管理 9、资产维修…

c++笔记理解

1.封装 &#xff08;1&#xff09;构造函数不是必须在的 可以通过行为修改属性 &#xff08;2&#xff09;private和protected区别在于继承那里要学 &#xff08;3&#xff09;类默认是私有&#xff0c;struct是共有 私有的好处&#xff1a;控制数据的有效性&#xff0c;意…

MySQL 8.0.36 WorkBench安装

一、下载安装包 百度网盘链接&#xff1a;点击此处下载安装文件 提取码&#xff1a;hhwz 二、安装&#xff0c;跟着图片来 选择Custom,然后点Next 顺着左边框每一项的加号打开到每一个项的最底层&#xff0c;点击选中最底层的项目&#xff0c;再点击传过去右边的绿色箭头&a…

Codeforces Round 530 (Div. 2)

CF1099A Snowball 题目 有一个重量为 w 的雪球正在高度为 h 的地方向下滚动。每秒它的高度会减少 1。同时在高度 i 的位置它的重量会增加 i&#xff08;包括初始位置&#xff09; 同时在滚动的路线上有 2 块石头&#xff0c;第 i 块石头的高度为 hi​&#xff0c;即雪球会在 hi…

【论文阅读|基于 YOLO 的红外小目标检测的逆向范例】

基于 YOLO 的红外小目标检测的逆向范例 摘要1 引言2 相关工作2.1 逆向推理2.2 物体检测方法 3 方法3.1 总体架构3.2 逆向标准的可微分积分 4 实验4.1 数据集和指标4.2 实验环境4.4 OL-NFA 为少样本环境带来稳健性 5 结论 论文题目&#xff1a; A Contrario Paradigm for YOLO-b…

详解 leetcode_078. 合并K个升序链表.小顶堆实现

/*** 构造单链表节点*/ class ListNode{int value;//节点值ListNode next;//指向后继节点的引用public ListNode(){}public ListNode(int value){this.valuevalue;}public ListNode(int value,ListNode next){this.valuevalue;this.nextnext;} }package com.ag; import java.ut…

[树形DP] 最长乘积链

题目 1.最长乘积链 - 蓝桥云课 (lanqiao.cn) 初始思路 对问题进行分析&#xff0c;对每个点dfs去求走不同路的最远距离与次远距离求乘积&#xff0c;时间复杂度为O(n^2) 看了答案怎么弄的优化 解题思路 总的来说 预处理&#xff08;对每个结点的信息进行统计&#xff09…

AWS无服务器直播解决方案

随着媒体系统的发展&#xff0c;越来越多的直播客户想要一个即开即用的平台&#xff0c;在不需要管理和运维底层资源的同时使用一站式的媒体平台。九河云对多家云厂商有所了解及有一定合作&#xff0c;下面将按客户的需求介绍aws的无服务器直播解决方案。 架构概述&#xff1a…