一文学透设计模式——工厂模式

在这里插入图片描述

工厂模式

概念

牛马人生公司最近开启了线上直播,直播中牛马人生公司宣称他们建造了一家世界上最为先进的工厂,任何人只要去到工厂面前,告诉工厂你要什么牌子的汽车,工厂就会给你一辆什么牌子的汽车。

这引起了粉丝朋友的注意,纷纷来到工厂一探究竟。

实现步骤

下面我们用代码来表示这个逻辑。

  1. 牛马人生公司重新定义了汽车的概念,他在幼儿园发出了100份的问卷调查,得到了汽车的定义,以及该拥有的功能。

    /*** 汽车的接口定义** @author wanggt* @date 2023-06-17 20:45:27*/
    public interface Car {/*** 往前走** @author wanggt* @date 2023-06-17 20:46:21*/void run();
    }
    
  2. 得到了汽车的最先进的概念之后,牛马人生公司开始设计一个拥有世界上最先进理念的工厂,一家可以制造任何汽车的工厂。在牛马人生公司的设想中,最开始支持的是五菱神车和小鹏汽车。

    /*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/
    public class CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @param name 汽车名称** @author wanggt* @date 2023-06-17 21:00:09*/public static Car getCar(String name) {if ("五菱".equals(name)) {return new WuLingCar();} else if ("小鹏".equals(name)) {return new XiaoPengCar();} else {return null;}}
    }
    
  3. 但是牛马人生公司并不知道汽车的制造方法,所以找到了小鹏和五菱的汽车厂商,学习了汽车的制造技术,以及授权。

    /*** 五菱神车** @author wanggt* @date 2023-06-17 20:57:00*/
    public class WuLingCar implements Car {@Overridepublic void run() {System.out.println("五菱神车,送货载人都可以,我跑得飞快");}
    }
    
    /*** 小鹏汽车。** @author wanggt* @date 2023-06-17 20:58:05*/
    public class XiaoPengCar implements Car {@Overridepublic void run() {System.out.println("小鹏汽车走啊走");}
    }
    
  4. 粉丝应邀而来,来到工厂前面,果然想要有啥车,工厂就会给啥车。只不过工厂的工程师说,目前工厂支持的车的类型还不多,后面会继续扩展的。

    public class SimpleFactoryDemo {public static void main(String[] args) {Car xiaoPengCar = CarFactory.getCar("小鹏");xiaoPengCar.run();System.out.println("===========");Car wuLingCar = CarFactory.getCar("五菱");wuLingCar.run();}
    }
    
    小鹏汽车走啊走
    ===========
    五菱神车,送货载人都可以,我跑得飞快
    

优缺点分析

我们来分析下牛马人生公司的这个工厂。其实他就是使用了简单工厂模式

优点是:减少了买一辆车的复杂性,我不需要知道汽车里面的构造是怎么样的,也不需要知道什么牌子的汽车就要到哪里去买车。顾客只需要告诉一个名字,这个工厂都可以给客户心目中的汽车。而且未来这个工厂还可以生产越来越多类型的汽车。

缺点呢,工厂的总工程师才不会告诉你,外表看起来光鲜亮丽的汽车工厂,里面是多么的杂乱。因为要制造的汽车类型太多了,每种汽车又有不同的配件。工厂已经不堪重负了。支持的汽车牌子越多,工厂里面就越混乱。

改进方案

日子一天天过去,汽车工厂兼容的汽车类型越来越多,工人们不得不连轴转。而且因为汽车工厂支持的汽车类型太多了,工厂里结构变得异常的复杂。而且性能也越来越低。

新招了一个设计师,刚进到工厂就辞职了。他说他就没有见过这么复杂的结构。

汽车工厂的总工程师想,这么下去可不行啊,全天下有多少汽车类型啊,要是都兼容了,那工厂估计吃不消啊。

于是,在总工程师薅掉了最后一根头发之后,想到了解决办法。

他可以使用工厂方法模式来改造工厂。虽然也是工厂模式,但是工厂方法模式有效避免了修改现有的工厂。可以减少修改,而通过扩展的方式来达到目的。这就是所谓的开闭原则

总工程师得意地想,姜还是老的辣。

重新设计之后的汽车工厂如下所示:

  1. 汽车的概念还是一样的。

    /*** 汽车的接口定义** @author wanggt* @date 2023-06-17 20:45:27*/
    public interface Car {/*** 往前走** @author wanggt* @date 2023-06-17 20:46:21*/void run();
    }
    
  2. 总工程师增加了一个汽车工厂的设计规范。这里就是跟之前不同的地方。

    /*** 汽车工厂类的接口定义。** @author wanggt* @date 2023-06-17 20:51:13*/
    public interface CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/Car getCar();
    }
    
  3. 根据汽车的设计规范,打造了一个专门生产五菱神车的工厂。

    /*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/
    public class WuLingCarFactory implements CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/@Overridepublic Car getCar() {return new WuLingCar();}
    }
    
    /*** 五菱神车** @author wanggt* @date 2023-06-17 20:57:00*/
    public class WuLingCar implements Car {@Overridepublic void run() {System.out.println("五菱神车,送货载人都可以,我跑得飞快");}
    }
    
  4. 同样,又打造了一个小鹏汽车的工厂。

    /*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/
    public class XiaoPengCarFactory implements CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/@Overridepublic Car getCar() {return new XiaoPengCar();}
    }
    
    /*** 小鹏汽车。** @author wanggt* @date 2023-06-17 20:58:05*/
    public class XiaoPengCar implements Car {@Overridepublic void run() {System.out.println("小鹏汽车走啊走");}
    }
    
  5. 粉丝听闻汽车工厂大改造,又来到汽车工厂来围观。发现了汽车工厂的似乎比以前要复杂了,还需要知道小鹏汽车工厂,五菱汽车工厂。纷纷有些不满,但总算还在意料之内。

    public class FactoryMethodDemo {public static void main(String[] args) {XiaoPengCarFactory xiaoPengCarFactory = new XiaoPengCarFactory();Car xiaoPengCar = xiaoPengCarFactory.getCar();xiaoPengCar.run();System.out.println("===========");WuLingCarFactory wuLingCarFactory = new WuLingCarFactory();Car wuLingCar = wuLingCarFactory.getCar();wuLingCar.run();}
    }
    
  6. 总工程师松了一口气,以后总算不用担心兼容新的汽车了。只要新建一个对应的工厂就可以生产新的汽车了。

可以看出来,简单工厂模式胜在简单,一个工厂类,一个静态方法就可以获取各种对象。工厂方法模式扩展性比较强,而且满足开闭原则。

选择使用哪一个,主要是看简单不简单。

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

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

相关文章

stm32与上位机电脑间最快的通信方式是什么?

对于小型多关节机械臂的控制电路设计,选择合适的通信方式可以提高MCU与上位机之间的实时性。以下是一些在STM32上常用的通信方式,你可以根据你的具体需求选择适合的: 串口通信(UART):串口通信是一种常见的…

opencv-34 图像平滑处理-2D 卷积 cv2.filter2D()

2D卷积是一种图像处理和计算机视觉中常用的操作,用于在图像上应用滤波器或卷积核,从而对图像进行特征提取、平滑处理或边缘检测等操作。 在2D卷积中,图像和卷积核都是二维的矩阵或数组。卷积操作将卷积核在图像上滑动,对每个局部区…

Netty学习(四)

文章目录 四. 优化与源码1. 优化1.1 扩展序列化算法jdk序列化与反序列化Serializer & AlgorithmConfigapplication.properties MessageCodecSharableMessage(抽象类) 测试序列化测试反序列化测试 1.2 参数调优1)CONNECT_TIMEOUT_MILLIS2&…

session 和 cookie 有什么区别

session和cookie是用于记录客户端信息的技术,都是用来跟踪浏览器用户身份的会话方式。 一、什么是 cookie ? cookie (数据存储在客户端)自带证明自己身份信息的标记 (跨页面间变量传递 :自己携带的一些信…

ansible配置文件案例

案例一 控制主机上的普通用户控制受控主机 控制端1台,受控端两台 1.将两台受控主机添加到/etc/hosts文件中 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhos…

Qt5.13引入QtWebApp的模块后报错: error C2440: “reinterpret_cast”: 无法从“int”转换为“quintptr”

1、开发环境 Win10-64 qt5.13 msvc2015-64bit-release 2、报错 新建一个demo工程。 引入QtWebApp的httpserver、logging、templateengine三个模块后。 直接运行,,此时报错如下: E:\Qt5.13.1\install\5.13.1\msvc2015_64\include\QtCore…

Java 8 中使用 Stream 遍历树形结构

在实际开发中,我们经常会开发菜单,树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理,我们一起来看看&#x…

GEE:矢量数据去除重复值(输出样本点数据的标签信息)

作者:CSDN @ _养乐多_ 本文记录了在GoogleEarthEngine(GEE)平台上,将样本点数据中某个字段的值去除重复值,并将剩下的值打印到控制台的代码。该代码可以用于快速在GEE平台上查询土地利用分类信息中landcover的类别信息。 矢量数据信息如下所示, 打印结果如下所示, 文章…

QT-QTableWidget设置单元项图标和图标大小

要设置 QIcon 的大小,你可以使用 QPixmap 来加载原始图像,并调用 QPixmap 的 scaled() 函数来缩放图像的尺寸。然后,将缩放后的 QPixmap 设置给 QIcon,最后将 QIcon 设置给 QTableWidgetItem 的图标。 下面是一个示例代码&#x…

Flask-SocketIO

一、简介: Flask-SocketIO使Flask应用程序可以实现客户端和服务器之间的低延迟双向通信。客户端应用程序可以使用 Javascript、Python、C、Java和Swift中的任何SocketIO客户端库或任何其他兼容客户端来建立与服务器的永久连接。 二、安装: pip instal…

GPS北斗卫星时钟服务器如何在各领域发挥作用

GPS北斗卫星时钟服务器如何在各领域发挥作用 GPS北斗卫星时钟服务器如何在各领域发挥作用 1.通信与网络:时钟服务器可用于确保通信网络中的各个设备具有高度精确的时间同步。这对于数据通信、日志记录、安全认证等方面至关重要。 2.金融交易:在金融行业…

基于weka手工实现ID3决策树

一、决策树ID3算法 相比于logistic回归、BP网络、支持向量机等基于超平面的方法,决策树更像一种算法,里面的数学原理并不是很多,较好理解。 决策树就是一个不断地属性选择、属性划分地过程,直到满足某一情况就停止划分。 当前样…

【TypeScript】类型断言的基本使用

类型断言的概念 有些时候开发者比TS本身更清楚当前的类型是什么&#xff0c;可以使用断言&#xff08;as&#xff09;让类型更加精确和具体。 类型断言&#xff08;Type Assertion&#xff09;表示可以用来手动指定一个值的类型。 类型断言语法&#xff1a; 值 as 类型 或 <…

Springboot整合activiti5,达梦数据库,mybatis中间件

Springboot整合activiti5&#xff0c;达梦数据库&#xff0c;mybatis中间件 问题现象解决方案 问题现象 由于工作流引擎不支持达梦数据库以及国产中间件&#xff0c;所以我们引入的时候会报错&#xff0c;这个时候就需要去改造代码和配置文件。各种文档和资料查找一天&#xf…

4.2的幂次方表示

【题目】 任何一个正整数都可以用2进制表示&#xff0c;例如&#xff1a;137的2进制表示为10001001。 将这种2进制表示写成2的次幂的和的形式&#xff0c;令次幂高的排在前面&#xff0c;可得到如下表达式&#xff1a;137 2^7 2^3 2^0 现在约定幂次用括号来表示&#xff0…

Kafka3.0.0版本——生产者如何提高吞吐量

目录 一、生产者提高吞吐量参数设置二、产者提高吞吐量代码示例 一、生产者提高吞吐量参数设置 batch.size&#xff1a;设置批次大小&#xff0c;默认16klinger.ms&#xff1a;设置等待时间&#xff0c;修改为5-100msbuffer.memory&#xff1a;设置缓冲区大小&#xff0c; 默认…

Node.js-http模块服务端请求与响应操作,请求报文与响应报文

简单案例创建HTTP服务端&#xff1a; // 导入 http 模块 const http require("http"); // 创建服务对象 const server http.createServer((request, response) > {// 设置编码格式&#xff0c;解决中文乱码问题response.setHeader("content-type", &…

升级mybatis-plus到3.5.3.1和JSQLParser 从4.3升级到4.6版本引起的插入问题解决

由于项目组件升级&#xff0c;所以需要升级mybatis-plus到3.5.3.1和JSQLParser 从4.3升级到4.6版本&#xff0c;但发现用标准的插入也会报错&#xff0c;如下&#xff1a; ### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Erro…

tomcat限制IP访问

tomcat可以通过增加配置&#xff0c;来对来源ip进行限制&#xff0c;即只允许某些ip访问或禁止某些来源ip访问。 配置路径&#xff1a;server.xml 文件下 标签下。与同级 <Valve className"org.apache.catalina.valves.RemoteAddrValve" allow"192.168.x.x&…

python练习10-8,10-9

10-8 def count_words(filename):try:with open(filename) as f:cf.read()except FileNotFoundError:print(f"Sorry,the file {filename} did not exist.")else:print(c)filenames[cats.txt,dogs.txt] for filename in filenames:filename.hanshu() #记错了在类中…