设计模式--工厂模式

普通创建对象的方式,如:

interface ICourse{public void record();
}class JavaCourse implements ICourse{@Overridepublic void record() {System.out.println("Java 课程");}
}
public class Test {public static void main(String[] args) {ICourse course = new JavaCourse();course.record();}
}

以上代码,父类ICourse指向子类JavaCourse的引用,应用层代码需要依赖JavaCourse,如果业务扩展,继续增加PythonCourse甚至更多,那么我们的客户端的依赖会变得越来越臃肿。因此,我们要想办法把这种依赖减弱,把创建细节隐藏。 

简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例,不属于GOF 23种设计模式。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。


interface ICourse{public void record();
}class JavaCourse implements ICourse{@Overridepublic void record() {System.out.println("Java 课程");}
}class PythonCourse implements ICourse{@Overridepublic void record() {System.out.println("Python 课程");}
}/*** 简单工厂类*/class CourseFactory{public ICourse create(String name){if("Java".equals(name)){return new JavaCourse();}else if("Python".equals(name)){return new PythonCourse();}else{return null;}}
}public class Test {public static void main(String[] args) {CourseFactory courseFactory = new CourseFactory();courseFactory.create("Java");}
}

为了更方便调用,也可以把create改为静态方法

如果业务继续扩展,那么工厂中的create()就需要修改代码逻辑,不符合开闭原则。因此可以采用反射技术进行优化:

/*** 简单工厂类*/class CourseFactory{public ICourse create(String className)  {if((null == className || "".equals(className))){try {return (ICourse) Class.forName(className).newInstance();} catch (Exception e) {e.printStackTrace();} }return null;}
}public class Test {public static void main(String[] args) {CourseFactory courseFactory = new CourseFactory();courseFactory.create("com.factory.simplefactory.JavaCourse");}
}

方法参数是字符串,可控性有待提升,而且还需要强制转型。 

/*** 简单工厂类*/class CourseFactory{public ICourse create(Class<? extends ICourse> clazz)  {if(null != clazz){try {return clazz.getDeclaredConstructor().newInstance();} catch (Exception e) {e.printStackTrace();}}return null;}
}public class Test {public static void main(String[] args) {CourseFactory courseFactory = new CourseFactory();courseFactory.create(JavaCourse.class);}
}

工厂方法模式(Factory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。

/*** 工厂模式*/
interface ICourseFactory{ICourse create();
}class JavaCourseFactory implements ICourseFactory{@Overridepublic ICourse create() {return new JavaCourse();}
}class PythonCourseFactory implements ICourseFactory{@Overridepublic ICourse create() {return new PythonCourse();}
}
public class Test {public static void main(String[] args) {ICourseFactory iCourseFactory = new JavaCourseFactory();ICourse iCourse = iCourseFactory.create();}
}

工厂方法适用以下场景:

  1. 创建对象需要大量重复的代码
  2. 客户端不依赖于产品类实例如何被创建、实现等细节
  3. 一个类通过其子类来指定创建哪个对象

工厂方法的缺点:

  1. 类的个数容易过多,增加复杂度
  2. 增加了系统的复杂性

抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。强调的是一系列相关的产品对象一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖具体实现。

interface INote{void edit();
}class JavaNote implements INote{@Overridepublic void edit() {System.out.println("编写Java 笔记");}
}
/*** 抽象工厂类*/
abstract class AbstractCourseFactory{public void init(){System.out.println("初始化基础数据");}protected abstract ICourse createCourse();protected abstract INote createNote();
}class JavaAbstractCourseFactory extends AbstractCourseFactory{@Overrideprotected ICourse createCourse() {super.init();return new JavaCourse();}@Overrideprotected INote createNote() {super.init();return new JavaNote();}
}public class Test {public static void main(String[] args) {AbstractCourseFactory abstractCourseFactory = new JavaAbstractCourseFactory();abstractCourseFactory.createCourse().record();abstractCourseFactory.createNote().edit();}
}

上述代码完整的描述了创建一个产品族的过程。但是如何如果将Video类加入其中,所有代码都需要调整,不符合开闭原则。抽象工厂方法的缺点是:

  1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
  2. 增加了系统的复杂性。 

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

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

相关文章

2024.2.23

1、消息队列代码 msgsnd.c #include<myhead.h> //定义一个消息类型 struct msgbuf {long mtype; //消息类型char mtext[1024]; //消息正文 };//定义一个宏&#xff0c;表示消息正文大小 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int …

Devc++ Easyx 实现 瓦片地图编辑数据导入游戏

导出的DLC 直接放入 exe 同文件夹下即可自动读取。 // 程序&#xff1a;DLC 自动读取加载框架示例 // 作者&#xff1a;民用级脑的研发记录 // 邮箱&#xff1a;1309602336qq.com // 编译环境&#xff1a;Devc/VC 2010/Visual Studio 2022&#xff0c;EasyX_20220901/Easyx_202…

Docker容器故障排查与解决方案

Docker是一种相对使用较简单的容器&#xff0c;我们可以通过以下几种方式获取信息&#xff1a; 1、通过docker run执行命令&#xff0c;或许返回信息 2、通过docker logs 去获取日志&#xff0c;做有针对性的筛选 3、通过systemctl status docker查看docker服务状态 4、通过…

转载:Linux全自动批量配置SSH免密

转载自 https://www.mr-mao.cn/archives/auto-configure-ssh-nopass-login.html 1、在主机的操作系统上安装expect 2、新建host_ip文件&#xff0c;内容格式如下 host_ip文件格式 172.16.1.100 password 172.16.1.101 password 172.16.1.102 password 172.16.1.103 pass…

[深度学习]图片相似度计算

理论铺垫&#xff1a;VGG16及其在图片对比中的应用 VGG16是一种深度学习模型&#xff0c;它属于卷积神经网络&#xff08;Convolutional Neural Networks, CNNs&#xff09;的一种&#xff0c;由牛津大学的视觉几何组&#xff08;Visual Geometry Group&#xff09;开发。这个…

数据安全治理实践路线(上)

基于以上数据安全治理实践理念&#xff0c;可以按照自顶向下和自底向上相结合的思路推进实践过程。一方面&#xff0c;组织自顶向下,以数据安全战略规划为指导,以规划、建设、运营、优化为主线&#xff0c;围绕构建数据安全治理体系这一核心&#xff0c;从组织架构、制度流程、…

React setState同步还是异步

React18 setState是同步还是异步&#xff1f;_react18 同步-CSDN博客 React18之前或者React18使用了ReactDOM.render&#xff0c;setState在React调度流程中是异步更新&#xff0c;在原生事件和setTimeout中是同步更新。React18使用ReactDOM.createRoot&#xff0c;那么默认都是…

“从根到叶:深入理解排序数据结构“

一.排序的概念及引用 1.1排序的概念 排序是指将一组数据按照一定的规则重新排列的过程。排序的目的是为了使数据具有有序性&#xff0c;便于查找、插入、删除等操作&#xff0c;提高数据的组织和管理效率。 稳定性是指如果序列中存在相等元素&#xff0c;在排序完成后&#…

LINUX中用C获得当前执行应用的全路径

之前有博文&#xff1a; LINUX中用C获得当前执行应用的所在路径_linux c语言 直接使用.\获取的路径是程序所在路径 还是命令执行路径-CSDN博客 这个代码也没问题。现实中有时取的路径并不对。比如说&#xff0c;我是../work/test&#xff0c;这个路径就不对了。简单的说&#…

nginx中的location

在 nginx 中&#xff0c;location 是用来匹配请求 URI 的指令&#xff0c;它告诉 NGINX 如何处理特定的请求。location 指令通常用于配置不同 URI 的访问规则&#xff0c;例如重定向、反向代理、设置缓存等。 以下是 location 指令的一般格式&#xff1a; location [ | ~ | …

网卡本质,网络发展(局域网,广域网概念)

目录 引入 网卡的本质 网络的发展 引入 早期 局域网LAN&#xff08;Local Area Network&#xff09; 广域网WAN&#xff08;Wide Area Network&#xff09; 注意 引入 前面我们已经学习了很多关于linux系统的知识,其中文件系统和线程尤为繁杂 而网络其实也算系统的一部…

Dart:谷歌的现代化编程语言之旅

内容概览 引言&#xff1a;一、Dart语言简介二、Dart的特点三、Dart在Flutter中的应用四、Dart的未来展望五 与JavaScript代码对比结语&#xff1a; 引言&#xff1a; 在Web和移动应用开发领域&#xff0c;JavaScript一直是最流行的编程语言之一。然而&#xff0c;随着技术的不…

2024年开发者的最好选择!!没有之一

中国银河证券1月23日明确指出&#xff1a;鸿蒙应用将在2024年迎来爆发。 2024年Q2推出开发者Beta版&#xff0c;2024年Q4推出商用版。今年年终将有 5000 款应用完成原生鸿蒙开发&#xff0c;未来支持 50 万款应用。覆盖便捷生活、出行文旅、金融便利、社交资讯、生产力工具、影…

2024能源动力、机械自动化与航天航空技术国际学术会议(ICEPMAT2024)

2024能源动力、机械自动化与航天航空技术国际学术会议(ICEPMAT2024) 会议简介 能源动力、机械自动化和航空航天技术国际学术会议&#xff08;ICEPMAT2024&#xff09;将于2024年在北京举行。会议将探讨能源动力、机械自动化、航空航天技术领域的新研究热点、核心技术和发展趋…

【Git】:远程仓库操作

远程仓库操作 一.理解版本控制系统二.远程仓库1.克隆2.Push操作3.fetch操作4. .gitnore文件 一.理解版本控制系统 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地&#xff01;也就是在你的笔记本或者计…

Camtasia Studio2024破解版屏幕录像和视频编辑软件

Camtasia Studio是一款专业的屏幕录像和视频编辑软件&#xff0c;它可以用来进行多种工作&#xff1a; 屏幕录制&#xff1a;Camtasia Studio可以录制电脑屏幕上的任何活动&#xff0c;如软件操作、演示、游戏过程等&#xff0c;非常适合制作教学视频、软件教程、游戏解说等。…

京东前端笔试(附答案解答)

引言 我目前本科大四&#xff0c;正在春招找前端&#xff0c;有大厂内推的友友可以聊一聊&#xff0c;球球给孩子的机会吧。 我整理了一份10w字的前端技术文档&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink &#xff0c;对…

什么是汽车抛负载Load dump

1.什么是抛负载 抛负载&#xff0c;英文为Load dump&#xff0c;是指断开电源与负载的瞬间&#xff0c;由于负载突变而引起电源电压急剧变化。在汽车电子领域&#xff0c;抛负载是指在蓄电池充电时&#xff0c;断开发电机与蓄电池的连接而引起发电机输出大电压尖峰&#xff0c…

用户请求到响应可能存在的五级缓存

用户请求到响应可能存在的五级缓存 当用户在浏览器中输入URL进行访问时&#xff0c;请求并不是直接达到服务器&#xff0c;而是会经历多级缓存&#xff0c;以提高网络效率。本文将详细介绍用户请求到响应可能会经历的五个缓存级别&#xff1a;浏览器缓存&#xff0c;代理缓存&…

【Linux】一站式教会:Ubuntu(无UI界面)使用apache-jmeter进行压测

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Java…