设计模式三:工厂模式
工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式,其中后两者属于23中设计模式
各种模式中共同用到的实体对象类:
//汽车类:宝马X3/X5/X7;发动机类:B48TU、B48//宝马汽车接口
public interface BMWCar {void show();
}//发动机接口
public interface Engine {void show();
}//宝马X3
public class BMWX3 implements BMWCar {@Overridepublic void show() {System.out.println("华晨宝马X3:39.96-48.69万");}
}//宝马X5
public class BMWX5 implements BMWCar {@Overridepublic void show() {System.out.println("华晨宝马X5:58.75-80万");}
}//宝马X7
public class BMWX7 implements BMWCar {@Overridepublic void show() {System.out.println("华晨宝马X3:89.35-102.25万");}
}//B48TU发动机
public class B48TUEngine implements Engine {@Overridepublic void show() {System.out.println("B48TU:涡轮增压 压缩比 11:1");}
}//B48发动机
public class B48Engine implements Engine {@Overridepublic void show() {System.out.println("B48:涡轮增压 压缩比 10.2:1");}
}
1、简单工厂模式
- 模型
用户只需要使用汽车生产工厂,告诉其想要生产的车型,具体生产细节不需要了解即可得到希望车型
- 实现
//简单工厂类
public class BMWCarFactory {public static BMWCar buy(String carName){switch (carName){case "BMWX5":return new BMWX5();case "BMWX3":return new BMWX3();default:return null;}}
}//测试
public class Consumer {public static void main(String[] args) {BMWCar bmwCar = BMWCarFactory.buy("BMWX5");if (bmwCar == null){System.out.println("无该车型");}assert bmwCar != null;bmwCar.show();}
}
简单工厂模式:
再添加一个宝马产品,就要修改factory类
1、使用进阶版简单工厂模式
2、使用工厂方法模式,即有自工厂生产对应车型,X5由X5Factory生产,X3由X3Factory生产,在添加一种车型,则对应添加一个工厂类型
简单工厂模式适用于的场景:
1、适用 于工厂类负责创建的对象较少的场景,
2、且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心。
简单工厂模式缺点:
1、工厂类的职业相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则
2、不易于扩展过于复杂的产品结构
2、进阶版简单工厂模式
//工厂类
public class BMWFactory {public static <T> T buy(Class<T> clazz){try {return clazz.newInstance();} catch (Exception e) {return null;}}
}//测试
public class Consumer {public static void main(String[] args) {BMWCar newCar = BMWFactory.buy(BMWX3.class);if (newCar == null){System.out.println("无该车型");}newCar.show();}
}
3、工厂方法模式
- 模型
//宝马工厂接口
public interface BMWCarFactory {BMWCar buy();
}//BMWX3工厂
public class BMWX3CarFactory implements BMWCarFactory {@Overridepublic BMWCar buy() {//可在这里做一定处理,对客户不可见,即对客户是透明的//......return new BMWX3();}
}//BMWX5工厂
public class BMWX5CarFactory implements BMWCarFactory {@Overridepublic BMWCar buy() {//可在这里做一定处理,对客户不可见,即对客户是透明的//......return new BMWX5();}
}//BMWX7工厂
public class BMWX7CarFactory implements BMWCarFactory {@Overridepublic BMWCar buy() {//可在这里做一定处理,对客户不可见,即对客户是透明的//......return new BMWX7();}
}//测试
public class Consumer {public static void main(String[] args) {BMWCar bmwCar = BMWCarFactory.buy("BMWX5");if (bmwCar == null){System.out.println("无该车型");}assert bmwCar != null;bmwCar.show();}
}
工厂方法模式的适用场景:
1、创建对象需要大量重复的代码
2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,一个类通过其子类来指定创建哪个对象。
工厂方法模式的优点:
1、用户只关系所需产品对应的工厂,无须关心创建细节。
2、加入新产品符合开闭原则,提高了系统的可扩展性。
工厂方法模式的缺点:
1、类的个数容易过多,增加了代码结构的复杂度。
2、增加了系统的抽象性和理解难度。
工厂方法模式:
如果处了汽车之外,新增加发动机产品 B48TU发动机(X5搭载) 和 B48发动机(X3搭载)
那么需要新增发动机工厂接口、B48TU工厂、B48工厂、发动机接口、B48TU发动机、B48发动机
如下图所示
4、抽象工厂模式
- 模型
- 实现
//宝马工厂接口
public interface BMWFactory {BMWCar buyCar();Engine buyEngine();
}//宝马X3工厂
public class BMWX3Factory implements BMWFactory {@Overridepublic BMWCar buyCar() {return new BMWX3();}@Overridepublic Engine buyEngine() {return new B48Engine();}
}//宝马X5工厂
public class BMWX5Factory implements BMWFactory {@Overridepublic BMWCar buyCar() {return new BMWX5();}@Overridepublic Engine buyEngine() {return new B48TUEngine();}
}//测试
public class Consumer {public static void main(String[] args) {BMWFactory factory = new BMWX3Factory();factory.buyCar().show();factory.buyEngine().show();}
}
抽象工厂模式:
将不同种类,同一等级的类放在一个工厂加工
但是新增产品时需要修改工厂类
抽象工厂模式使用场景:
1、客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。
2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。
3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体的实现。
抽象工厂模式优点:
1、具体产品在应用层代码隔离,无须关系创建细节。
2、将一个系列的产品族统一到一起创建。
抽象工厂模式缺点:
1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
2、增加了系统的抽象性和理解难度。
5、spring中的工厂模式
Calendar.getInstance() //简单工厂模式
LoggerFactory、BeanFactory、FactoryBean //工厂方法模式
Calendar
if (aLocale.hasExtensions()) {String caltype = aLocale.getUnicodeLocaleType("ca");if (caltype != null) {switch (caltype) {case "buddhist":cal = new BuddhistCalendar(zone, aLocale);break;case "japanese":cal = new JapaneseImperialCalendar(zone, aLocale);break;case "gregory":cal = new GregorianCalendar(zone, aLocale);break;}}
}
BeanFactory
public class TestBeanFactory {public static void main(String[] args) {DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// bean 的定义(class, scope, 初始化, 销毁)AbstractBeanDefinition beanDefinition =BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();beanFactory.registerBeanDefinition("config", beanDefinition);// 给 BeanFactory 添加一些常用的后处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);});// 打印BeanFactory中Beanfor (String name : beanFactory.getBeanDefinitionNames()) {System.out.println(name);}}@Configurationstatic class Config {@Beanpublic Bean1 bean1() {return new Bean1();}@Beanpublic Bean2 bean2() {return new Bean2();}}static class Bean1 {private static final Logger log = LoggerFactory.getLogger(Bean1.class);public Bean1() {log.debug("构造 Bean1()");}@Autowiredprivate Bean2 bean2;public Bean2 getBean2() {return bean2;}}static class Bean2 {private static final Logger log = LoggerFactory.getLogger(Bean2.class);public Bean2() {log.debug("构造 Bean2()");}}
}
相关文章:

设计模式三:工厂模式
工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式,其中后两者属于23中设计模式 各种模式中共同用到的实体对象类: //汽车类:宝马X3/X5/X7;发动机类:B48TU、B48//宝马汽车接口 public interface BMWCar {void s…...

2024.2.15 模拟实现 RabbitMQ —— 消息持久化
目录 引言 约定存储方式 消息序列化 重点理解 针对 MessageFileManager 单元测试 小结 统一硬盘操作 引言 问题: 关于 Message(消息)为啥在硬盘上存储? 回答: 消息操作并不涉及到复杂的增删查改消…...

【技巧】金融企业在搭建服务器时,选择私有云方案还是全栈专属云?
金融企业在搭建服务器时,选择私有云方案还是全栈专属云,需要根据企业的具体需求和情况进行综合考虑。Cloud Ace云一作为谷歌云全球战略合作伙伴,专注于企业级出海云服务 ,为大家带来两种方案的优劣势比较: 私有云 优势…...

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(10)模型评测
目录 一、模型评测的定义 二、模型评测的方法 三、模型评测的原理 四、涉及的关键技术 五、实例阐述 今天是2.2机器学习开发任务实例的最后一个部分——模型评测。 不同的模型计算出的MSE值会有差异,通过模型的选择,参数的变换,可以比较…...

【C++游戏开发-03】贪吃蛇
文章目录 前言一、工具准备1.1游戏开发框架1.2visual studio2022下载1.3easyX下载1.4图片素材 二、逻辑分析2.1数据结构2.2蛇的移动2.3吃食物2.4游戏失败 三、DEMO代码实现四、完整源代码总结 🐱🚀个人博客https://blog.csdn.net/qq_51000584?typeblo…...

如何理解CSS的边框宽度?
CSS 边框宽度学习手记 CSS 边框宽度小概念 在CSS的世界里,border-width这个属性真的很实用,它能帮我指定HTML元素四周边框的宽度。这个宽度嘛,可以用像素px、点pt、厘米cm、相对单位em这些来表示,很方便吧!还有呢&am…...

java 写入写出 zip
package com.su.test.aaaTest.ioTest; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** 将文件压缩到 zip 中 */ public c…...

问题解决:‘telnet‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件
当在windows终端中运行telnet指令的时候,发现指令不可用,原因在于系统没安装telnet功能。 解决方法: 打开控制面板–》程序–》启用或关闭windows功能–》勾选Telnet客户端,点击确定即可。...

从基础到高级:Linux用户与用户组权限设置详解
目录 博客前言: 一.简介 1.用户的定义 用户账户分类 2.用户组的定义 二.用户的相关linux语法 1.创建用户(useradd) 2.删除用户(userdel) 3.修改用户(usermod) 4.修改用户密码 5.su切…...
【感知机】感知机(perceptron)学习算法知识点汇总
机器学习——感知机 感知机(perceptron)是一种二分类的线性模型,属于判别模型,也称为线性二分类器。输入为实例的特征向量,输出为实例的类别(取1和-1)。可以视为一种使用阶梯函数激活的人工神经元,例如通过梅尔频率倒谱系数(MFCC…...

蓝桥杯:C++二分算法
在基本算法中,二分法的应用非常广泛,它是一种思路简单、编程容易、效率极高的算法。蓝桥杯软件类大赛中需要应用二分法的题目很常见。 二分法有整数二分和实数二分两种应用场景 二分法的概念 二分法的概念很简单,每次把搜索范围缩小为上一…...

Leetcode刷题笔记题解(C++):83. 删除排序链表中的重复元素
思路:链表相关的问题建议就是画图去解决,虽然理解起来很容易,但就是写代码写不出来有时候,依次去遍历第二节点如果与前一个节点相等则跳过,不相等则遍历第三个节点 /*** Definition for singly-linked list.* struct …...

@ 代码随想录算法训练营第8周(C语言)|Day56(动态规划)
代码随想录算法训练营第8周(C语言)|Day56(动态规划) Day56、动态规划(包含题目 ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组 ) 300.最长递增子序列 题目描述 给你一个整数…...

C# OpenCvSharp DNN Image Retouching
目录 介绍 模型 项目 效果 代码 下载 C# OpenCvSharp DNN Image Retouching 介绍 github地址:https://github.com/hejingwenhejingwen/CSRNet (ECCV 2020) Conditional Sequential Modulation for Efficient Global Image Retouching 模型 Model Properti…...

通过Docker Compose的方式在Docker中安装Maven环境
目前可以说 Docker 已经是在开发部署中成为主流,所以我们很多环境和工具都会安装在 Docker 容器中,Maven 环境是 SpringBoot 项目中最常用的依赖管理工具。当我们使用自动运维工具如 Ansible、Chef 、Puppet、Walle、Spug等)管理和部署 Maven…...

Python实现线性逻辑回归和非线性逻辑回归
线性逻辑回归 # -*- coding: utf-8 -*- """ Created on 2024.2.20author: rubyw """import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import classification_report from sklearn import preprocessing from sklearn…...

【软考】软件维护
目录 一、说明二、正确性维护三、适应性维护四、完善性维护五、预防性维护 一、说明 1.软件维护主要是根据需求变化或硬件环境的变化对应用程序进行部分或全部修改 2.修改时应充分利用源程序,修改后要填写程序修改登记表,并在程度变更通知书上写明新旧程…...

突破性创新:OpenAI推出Sora视频模型,预示视频制作技术的未来已到来!
一、前言 此页面上的所有视频均由 Sora 直接生成,未经修改。 OpenAI - Sora is an AI model that can create realistic and imaginative scenes from text instructions. 2024 年 2 月 16 日,OpenAI 发布 AI 视频模型 Sora,60 秒的一镜到底…...

【Web前端笔记10】CSS3新特性
10 CSS3新特性 1、圆角 2、阴影 (1)盒阴影 3、背景渐变 (1)线性渐变(主要掌握这种就可) (2)径向渐变 &…...

LabVIEW荧光显微镜下微管运动仿真系统开发
LabVIEW荧光显微镜下微管运动仿真系统开发 在生物医学研究中,对微管运动的观察和分析至关重要。介绍了一个基于LabVIEW的仿真系统,模拟荧光显微镜下微管的运动过程。该系统提供了一个高效、可靠的工具,用于研究微管与运动蛋白(如…...

【Java面试】MQ(Message Queue)消息队列
目录 一、MQ介绍二、MQ的使用1应用解耦2异步处理3流量削峰4日志处理5消息通讯三、使用 MQ 的缺陷1.系统可用性降低:2.系统复杂性变高3.一致性问题四、常用的 MQActiveMQ:RabbitMQ:RocketMQ:Kafka:五、如何保证MQ的高可用?ActiveMQ:RabbitMQ:RocketMQ:Kafka:六、如何保…...

【安卓基础1】初识Android
🏆作者简介:|康有为| ,大四在读,目前在小米安卓实习,毕业入职。 🏆安卓学习资料推荐: 视频:b站搜动脑学院 视频链接 (他们的视频后面一部分没再更新,看看前面…...

08-静态pod(了解即可,不重要)
我们都知道,pod是kubelet创建的,那么创建的流程是什么呐? 此时我们需要了解我们k8s中config.yaml配置文件了; 他的存放路径:【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [rootk8s231 ~]# vim /var/lib…...

PROBIS铂思金融破产后续:ASIC牌照已注销
2024年1月31日,PROBIS铂思金融的澳大利亚ASIC牌照 (AFSL 338241) 被注销《差价合约经纪商PROBIS宣布破产,澳大利亚金融服务牌照遭暂停》,这也就意味着,PROBIS铂思金融目前已经没有任何金融牌照。 值得注意的是,时至今日…...

数字世界的探索者:计算机相关专业电影精选推荐
目录 推荐计算机专业必看的几部电影 《黑客帝国》 《社交网络》 《乔布斯传》 《心灵捕手》 《源代码》 《盗梦空间》 《头号玩家》 《我是谁:没有绝对安全的系统》 《战争游戏》(WarGames) 《模仿游戏》(The Imitation Game) 《硅谷》(Silicon Valley) …...

Spring Boot项目中TaskDecorator的应用实践
一、前言 TaskDecorator是一个执行回调方法的装饰器,主要应用于传递上下文,或者提供任务的监控/统计信息,可以用于处理子线程与主线程间数据传递的问题。 二、开发示例 1.自定义TaskDecorator import org.springframework.core.task.Task…...

511. 游戏玩法分析 I
文章目录 题意思路代码 题意 题目链接 统计每个用户第一次登陆平台时间 思路 代码 select player_id, min(event_date) as first_login from Activity group by player_id;...

大模型训练流程(三)奖励模型
为什么需要奖励模型 因为指令微调后的模型输出可能不符合人类偏好,所以需要利用强化学习优化模型,而奖励模型是强化学习的关键一步,所以需要训练奖励模型。 1.模型输出可能不符合人类偏好 上一篇讲的SFT只是将预训练模型中的知识给引导出来…...

替换if...else的锦囊妙计
目录 前言 一、又臭又长的if...else 二、消除if...else的锦囊妙计 1、使用注解 2、动态拼接名称 3、模板方法判断 4.策略工厂模式 5.责任链模式 6、其他的消除if...else的方法 1.根据不同的数字返回不同的字符串 2.集合中的判断 3.简单的判断 4.spring中的判断 原文…...

新建一个flask项目
在Flask中创建一个新的项目,您可以遵循以下步骤: 确保您已经安装了Python环境。如果还未安装Flask,可以通过pip来安装: pip install flask创建一个新的文件夹作为您的项目文件夹,例如myflaskapp: mkdir …...