3、设计模式之工厂模式2(Factory)

一、什么是工厂模式
工厂模式属于创建型设计模式,它用于解耦对象的创建和使用。通常情况下,我们创建对象时需要使用new操作符,但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口,使得我们可以在不暴露对象创建逻辑的情况下创建对象。

二、工厂分类
工厂模式分为三种类型:简单工厂、方法工厂和抽象工厂,其本质就是对获取对象过程的抽象。

三、应用场景
3.1 生活场景
你需要一辆汽车,可以直接从工厂里提货,而不用关心它具体是怎么实现的
Hibernate换数据库只需要换方言和驱动就可以
3.2 java场景

BeanFactory:它是Spring
IoC容器的核心接口,通过读取配置文件或注解来创建Bean实例,并将它们注入到其他对象中。BeanFactory使用了工厂模式来隐藏具体的对象实例化过程,客户端只需要通过接口获取Bean对象,而不需要关心具体的实例化细节。
FactoryBean:是一种更高级别的工厂模式实现,用于创建特定类型的Bean对象。与普通的BeanFactory不同,FactoryBean的getObject()方法可以返回任意类型的对象实例,并且可以通过配置方式创建和管理实例。
Executors:提供了一系列的工厂方法来创建线程池(ThreadPoolExecutor)及其相关组件。
Charset:提供了一系列的静态工厂方法,如forName()、availableCharsets()等,用于创建Charset实例。

在这里插入图片描述
4.1 传统模式
在介绍工厂模式之前先来看看传统模式,以卖包子为例,如下:

 //简单的制作流程
public BaoZi createBaoZi() {BaoZi baozi = new BaoZiImpl();//准备材料baozi.prepare();//制作包子baozi.make();//蒸包子baozi.braise();return baozi;
}

包子肯定有很多种类吧,那我们可以直接在上述代码中添加根据包子的种类生成不同类型的对象

/**
* 包子肯定有不同的馅:酸菜、豆沙、猪肉,那么他的材料、售价等方式也不同
* 我们可以直接在上述代码中,添加根据包子的不同种类生成不同的对象。
*/
public BaoZi createBaoZi(String type) {BaoZi baoZi = null;switch (type){case "suancai":baoZi=new SuanCaiBaoZi();break;case "dousha":baoZi=new DouShaBaoZi();break;case "pork":baoZi=new PorkBaoZi();break;default:throw new IllegalArgumentException("Invalid BaoZi Type");}//准备材料baoZi.prepare();//制作包子baoZi.make();//蒸包子baoZi.braise();return baoZi;
}

Test:

  //1.传统模式@Testvoid traditonal(){SaleBaoZi saleBaoZi=new SaleBaoZi();//以猪肉包为例saleBaoZi.createBaoZi("pork");}

4.2 简单工厂模式
简单工程根据客户端的需求创建具体的实例,这种模式对调用者隐藏了实例创建的过程,也使得创建过程更加容易维护。

还是以卖包子为例,简单工厂模式实现如下:


/*** 2.简单工厂方法:希望能够创建一个对象,但创建过程比较复杂,希望对外隐藏这些细节*/
public class SimpleFactory {public static BaoZi createBaoZi(String type){BaoZi baoZi=null;switch (type){case "suancai":baoZi=new SuanCaiBaoZi("酸菜包");break;case "dousha":baoZi=new DouShaBaoZi("豆沙包");break;case "pork":baoZi=new PorkBaoZi("猪肉包");case "beef"://老板拓展业务了,新加了一个牛肉包类型的包子,那对于简单工厂模式而言,//于是就得修改源代码,那么就违反了ocp原则,假如新增100个?baoZi=new BeefBaoZi("牛肉包");break;default:throw new IllegalArgumentException("Invalid BaoZi Type");}return baoZi;}
}

Test:

  //2.简单工厂模式@Testvoid simpleFactory(){//以猪肉包为例BaoZi pork = SimpleFactory.createBaoZi("pork");pork.prepare();pork.make();pork.braise();}

相比传统模式,从类图上就可以看出来,在sale和baozi中间又加了一层。

通过封装SimpleFactory这个类,我们将sale和baozi进行了解耦合。
4.3 方法工厂模式
简单工厂模式下,如果老板拓展业务了,加了一个牛肉种类的包子,就得在源码基础上修改,那么这就违背了开闭原则(ocp),即对扩展开放,对修改关闭。于是,为了解决这个问题,就又了工厂方法模式。

工厂方法模式是一种更加抽象的工厂模式,它将工厂的职责抽象为接口,由具体的工厂实现创建具体的对象。工厂方法模式弱化了工厂的实现,使得每个工厂只负责一个产品的创建。

抽象工厂MeAbStractFactory:

public interface MeAbstractFactory {BaoZi createBaoZi();
}

DouShaFactory:

//豆沙包
public class DouShaFactory implements MeAbstractFactory {@Overridepublic BaoZi createBaoZi() {return new DouShaBaoZi("豆沙包");}
}

PorkFactory:

//猪肉包
public class PorkFactory implements MeAbstractFactory {@Overridepublic BaoZi createBaoZi() {return new PorkBaoZi("猪肉包");}
}

BeefFactory:

//牛肉包
public class BeefFactory implements MeAbstractFactory {@Overridepublic BaoZi createBaoZi() {return new BeefBaoZi("牛肉包");}

Test:

  //3.方法工厂模式@Testvoid methodFactory(){MeAbstractFactory factory=new PorkFactory();BaoZi pork = factory.createBaoZi();pork.prepare();pork.make();pork.braise();}

之前的SimpleFactory在createBaoZi中直接就new出来了,但在方法工厂中,我们将createBaoZi这个动作推迟到了MeAbStactFactory的子类(XXFactory)中才完成。

好处就是,比如后期要卖个羊肉包,我们直接编写个羊肉包类,然后实现MeAbstractFactory类就,实现它自己的功能,这样完全不用修改原来的代码了,也就解决了违反OCP原则的问题。

4.4 抽象工厂模式
抽象工厂模式是基于工厂方法模式的基础上进行的。在这种模式中,每一个工厂不再只负责一个产品的创建,而是负责一组产品的创建。抽象工厂模式将每个产品组都提取为一个接口,每个工厂都负责一个产品组。

     假如老板的生意做大了,在北京开了个分店,并且不止卖包子,还卖蛋糕,那么该怎么拓展呢,很简单,只需要在抽象工厂类中新增创建蛋糕的抽象方法就行,如下:
AbstractFactorypublic interface AbstractFactory {//制作包子BaoZi createBaoZi(String type);//制作蛋糕Cake createCake(String type);
}

BJFactory:

//北京分店
public class BJFactory implements AbstractFactory{@Overridepublic BaoZi createBaoZi(String type) {BaoZi baoZi=null;switch (type){case "beef":baoZi=new BJBeefBao("北京牛肉包");break;case "pork":baoZi=new BJPorkBao("北京猪肉包");default:break;}return baoZi;}@Overridepublic Cake createCake(String type) {Cake cake=null;switch (type){case "apple":cake=new BJAppleCake("北京苹果蛋糕");break;case "pear":cake=new BJPearCake("北京梨味蛋糕");default:break;}return cake;}
}

Test:

//4.抽象工厂模式
@Test
void abstractFactory(){AbstractFactory factory=new BJFactory();Cake apple = factory.createCake("apple");BaoZi pork = factory.createBaoZi("pork");apple.prepare();apple.make();apple.bake();apple.sale();pork.prepare();pork.make();pork.braise();pork.sale();
}

5.1 简单工厂模式

优点:

简单工厂模式实现简单,易于理解和使用; 可以对对象的创建进行集中管理,客户端和具体实现解耦。
缺点:

工厂类负责创建所有对象,如果需要添加新类型的产品,则需要修改工厂类的代码,这违反了开闭原则; 工厂类职责过重,导致单一职责原则被破坏。
适用场景:

工厂类负责创建的对象较少,客户端不需要知道对象的创建过程; 客户端需要根据传递的参数来获取对应的对象。

5.2 方法工厂模式

优点:

方法工厂模式具有良好的可扩展性,如果需要添加新类型的产品,只需要添加对应的工厂方法即可;
与简单工厂模式相比,方法工厂模式更符合开闭原则和单一职责原则。
缺点:

需要客户端自行选择使用哪个工厂方法,不能像简单工厂模式那样直接传参获取对应对象,因此对客户端的编写有一定要求。 适用场景:

应用中需要创建的对象较少,但是需要具备良好的可扩展性; 客户端可以自行选择创建哪种对象。

5.3 抽象工厂

优点:

抽象工厂模式可以创建多个产品族的产品,这些产品之间有相互依赖或约束关系,有助于保持系统的一致性和稳定性;
客户端与具体产品解耦,通过产品族的方式进行管理。
缺点:

抽象工厂模式增加了系统的抽象性和理解难度,不易于理解和修改; 新增产品族时需要修改工厂接口、工厂实现类和产品类,增加了系统的复杂性。
适用场景:

系统需要一系列相互依赖或约束的产品; 客户端不需要知道具体产品的创建过程,只需要知道产品族即可。

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

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

相关文章

【小白学机器学习8】统计里的自由度DF=degree of freedom, 以及关于df=n-k, df=n-k-1, df=n-1 等自由度公式

目录 1 自由度 /degree of freedom / df 1.1 物理学的自由度 1.2 数学里的自由度 1.2.1 数学里的自由度 1.2.2 用线性代数来理解自由度(需要补充) 1.2.3 统计里的自由度 1.3 统计学里自由度的定义 2 不同对象的自由度 2.1 纯公式的自由度&#…

idea:忽略不要搜索unpackage文件夹

开发vue时搜索关键字,会搜索到编译后的文件,如unpackage。(注意这个是idea工具,和Git忽略是有区别的) File->Settings->Editor->File Types

【C++ 设计模式】策略模式与简单工厂模式的结合

文章目录 前言一、为什么需要策略模式简单工厂模式二、策略模式简单工厂模式实现原理三、UML图四、示例代码总结 前言 在软件设计中,常常会遇到需要根据不同情况选择不同算法或行为的情况。策略模式和简单工厂模式是两种常见的设计模式,它们分别解决了对…

.Net Core 中间件验签

文章目录 为什么是用中间件而不是筛选器?代码实现技术要点context.Request.EnableBuffering()指针问题 小结 为什么是用中间件而不是筛选器? 为什么要用中间件验签,而不是筛选器去验签? 1、根据上图我们可以看到,中间件在筛选器之…

专业无网设备如何远程运维?向日葵远程控制能源场景案例解析

清洁能源领域,拥有庞大的上下游产业链,涉及的相关工业设备门类多、技术覆盖全、行业应用广。在这一领域内,相关专业设备的供应商的核心竞争力除了本身产品的技术能力之外,服务也是重要的一环。 某企业作为致力于节能环保方向的气…

spy分析文件另存为弹框【selenium】

有时需要下载多个文件,但是不想保存在同一个目录下,需要做两步 selenium设置浏览器默认下载路径,这个路径需要是个不存在的路径操作文件另存为弹框 文章目录 selenium设置浏览器默认下载路径操作文件另存为弹框 selenium设置浏览器默认下载路…

使用docker-compose管理freeswitch容器

概述 之前的文章我们介绍过如何将freeswitch做成docker镜像,也使用命令行模式正常启动了fs的docker容器。 但是当我们需要同时管理多个docker容器的时候,还是使用docker-compose更简单。 环境 CENTOS 7 docker engine:Version 25.0.3 D…

【快捷部署】002_Flink(1.17.2)

📣【快捷部署系列】002期信息 编号选型版本操作系统部署形式部署模式002Flink1.17.2CentOS 7.Xtgz包单机 👉 演示视频 Flink一键安装(本地模式) install-flink.sh 脚本内容 #!/bin/bash ####变量 ###执行脚本的当前目录 mydir$…

使用IDEA2023创建传统的JavaWeb项目并运行与调试

日期:2024-0312 作者:dusuanyun 文档环境说明: OS:Deepin 20.9(Linux) JDK: OpenJDK21 Tomcat:10.1.19 IDEA: 2023.3.4 (Ultimate Edition) 本文档默认已经安装JDK及环境变量的配置。 关键词…

景联文科技:提供通用多模态数据,助力AI多模态领域实现飞跃式发展

回顾2023年,以ChatGPT为代表的通用人工智能大模型在全球范围内掀起了新一轮人工智能产业发展浪潮,我国人工智能大模型市场呈现百“模”争鸣、日新月异的迅猛发展态势。 根据大模型之家、钛媒体数据,2023年中国大模型市场规模达到147亿人民币&…

几何造型库 - osgModeling

基于osg的几何造型库(osgModeling-0.1.1)的编译成果和示例: basic: boolean: bsp-tree:

bash: mysqldump: command not found

问题:在linux上执行mysql备份的时候,出现此异常 mysqldump命令找不到 解决: 1、找到mysql目录(找到mysql可执行命令目录) which mysql 有图可知,mysql安装在: /usr1/local/java/mysql 2、my…

Seata 2.x 系列【11】多数据源分布式事务

有道无术,术尚可求,有术无道,止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址:https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 多数据…

linux下重启ORACLE

切换到oracle用户 su - oracle 登录oracle sqlplus / as sysdba 启动数据库 startup 退出数据库 exit 启动监听 lsnrctl start FINISH

老电脑装什么系统流畅

对于一些老旧电脑来说,重装系统是提升电脑性能的最佳选择。那么,老电脑装什么系统流畅呢?推荐Windows 7系统,它对硬件的需求相对较低。配置较低的电脑运行Windows 7可以更好地利用系统资源,提高电脑的运行速度和响应能…

57、服务攻防——应用协议RsyncSSHRDP漏洞批扫口令猜解

文章目录 口令猜解——Hydra-FTP&RDP&SSH配置不当——未授权访问—Rsync文件备份协议漏洞——应用软件-FTP&Proftpd搭建 口令猜解——Hydra-FTP&RDP&SSH FTP:文本传输协议,端口21;RDP:windows上远程终端协议…

WRF模型运行教程(ububtu系统)--III.运行WRF模型(官网案例)

零、创建DATA目录 # 1.创建一个DATA目录用于存放数据(一般为fnl数据,放在Build_WRF目录下)。 mkdir DATA # 2.进入 DATA cd DATA 一、WPS预处理 在模拟之前先确定模拟域(即模拟范围),并进行数据预处理&#xff08…

【计算机网络】UDP/TCP 协议

TCP 协议 一、传输层1. 再谈端口号2. 端口号范围划分3. 进程和端口号4. netstat5. pidof 二、UDP 协议1. UDP 协议端格式(报文)2. UDP 的特点3. 面向数据报4. UDP 的缓冲区 三、TCP 协议1. 认识 TCP2. TCP 协议段格式(1)4 位首部长度(2&#…

论文阅读:Editing Large Language Models: Problems, Methods, and Opportunities

Editing Large Language Models: Problems, Methods, and Opportunities 论文链接 代码链接 摘要 由于大语言模型(LLM)中可能存在一些过时的、不适当的和错误的信息,所以有必要纠正模型中的相关信息。如何高效地修改模型中的相关信息而不影…

MySQL--深入理解MVCC机制原理

什么是MVCC? MVCC全称 Multi-Version Concurrency Control,即多版本并发控制,维持一个数据的多个版本,主要是为了提升数据库的并发访问性能,用更高性能的方式去处理数据库读写冲突问题,实现无锁并发。 什…