Java设计模式(二)——工厂模式
当用户需要一个类的子类实例,且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时,可采用工厂模式;当用户需要系统提供多个对象,且希望和创建对象的类解耦时,可采用抽象工厂模式。
工厂模式一般分为简单工厂、工厂、抽象工厂三种情况,属于创建型设计模式。
1. 关键角色
两个关键的角色:产品和工厂
两个角色的几种关系:
(1)单一产品系
| 高档 | 中档 | 低档 | |
| 小汽车 | √ | √ | √ |
(2)多产品系,特征相同
| 高档 | 中档 | 低档 | |
| 小汽车 | √ | √ | √ |
| 公共汽车 | √ | √ | √ |
(3)多产品系,部分特征相同
| 高档 | 中档 | 低档 | |
| 小汽车 | √ | √ | √ |
| 公共汽车 | √ | √ |
(4)多产品系,无特征相同
| 高档 | 中档 | 低档 | |
| 小汽车 | √ | √ | |
| 公共汽车 | √ |
2. 简单工厂
简单工厂模式功能类编制步骤:
- 定制抽象产品接口:ICar
- 定制具体产品子类:UpCar MidCar DnCar
- 定制工厂类:CarSimpleFactory
对于工厂类 create() 方法的理解:
使用简单工厂的时候,通常不用创建简单工厂类的类实例,没有创建实例的必要,因此可以把简单工厂类实现成一个工具类,直接使用静态方法就可以了。也就是说,简单工厂的方法通常都是静态的,所以也被称为静态工厂。
(1)小汽车接口
public interface ICar {
}
(2)定义高、中、低档具体的汽车
public class UpCar implements ICar{
}
public class MidCar implements ICar{
}
public class DnCar implements ICar{
}
(3)简单工厂
public class CarSimpleFactory {public static final String UPTYPR = "uptype";public static final String MIDTYPR = "midtype";public static final String DNTYPR = "dntype";public static ICar create(String mark) {ICar obj = null;if (mark.equals(UPTYPR)) {obj = new UpCar();}else if (mark.equals(MIDTYPR)) {obj = new MidCar();}else if (mark.equals(DNTYPR)) {obj = new DnCar();}return obj;}
}
(4)测试
public class CarTest {public static void main(String[] args) {ICar obj = CarSimpleFactory.create("UPCAR");}
}
新的需求:
如果现在又新增加了一个超高档类型的汽车,在简单工厂模式下,需要做的工作有:
(1)新增ICar的子类SuperCar
(2)修改工厂类 SimpleCarFactory 中的create方法,增加SuperCar对象的判断选择分支。
能否不修改工厂类,就能完成所需功能呢?可以 使用工厂模式。
3. 工厂模式
工厂模式功能类编制步骤:
- 定义抽象产品接口
- 定义具体产品子类
- 定义抽象工厂类 AbstractFactory,有一个重要的create抽象方法
- 定义具体工厂子类
(1)定义小汽车接口
public interface ICar {
}
(2)定义高、中、低档具体的小汽车
public class UpCar implements ICar{
}public class MidCar implements ICar {
}public class DnCar implements ICar {
}
(3)定义抽象工厂
public abstract class AbstractFactory {public abstract ICar create();
}
(4)定义高档小汽车工厂
public class UpFactory extends AbstractFactory{@Overridepublic ICar create() {return new UpCar();}
}
(5)定义中档小汽车工厂
public class MidFactory extends AbstractFactory{@Overridepublic ICar create() {return new MidCar();}
}
(6)定义低档小汽车工厂
public class DnFactory extends AbstractFactory{@Overridepublic ICar create() {return new DnCar();}
}
(7)测试类
public class CarTest {public static void main(String[] args) {AbstractFactory obj = new UpFactory(); //多态创建高档工厂System.out.println(obj);ICar car = obj.create();}
}
工厂模式和简单工厂模式的区别:
- 工厂模式把简单工厂中的具体工厂类划分成两层,抽象工厂层和具体工厂子类层。
- create方法参数的理解,在简单工厂模式中,create(String mark) 是成员方法,表名在该方法中管理多个产品,根据mark的值产生并返回ICar对象;在工厂模式中,create是抽象方法,无参数,表名在具体的子类工厂中创建某个具体的产品。
- 工厂方法更易于软件的二次开发和维护,主要特征是:当需求分析发生变化时,只需要增加、删除相应的类,而不是修改已有的类。
例如,又生产了一种超高档的小汽车,只需要增加SuperCar及SuperFactory两个类即可:
public class SuperCar implements ICar{
}
public class SuperFactory extends AbstractFactory{@Overridepublic ICar create() {return new SuperCar();}
}
4. 抽象工厂
一般来说,简单工厂、工厂模式是单产品系的,而抽象工厂是多产品系得。从本质上讲,抽象工厂、工厂模式是统一得。
抽象工厂模式功能类编制步骤如下:
- 定制抽象产品接口 如 ICar IBus
- 定制具体产品子类 如 UpCar MidCar DnCar UpBus MidBus
- 定制抽象工厂类 如 AbstractFactory 有两个create方法,分别返回ICar 和 IBus对象
- 定制具体工厂子类
(1) 定义小汽车接口
public interface ICar {
}
定义高、中、低档小汽车
public class UpCar implements ICar {
}public class MidCar implements ICar {
}public class DnCar implements ICar {
}
(2)定义公共汽车接口
public interface IBus {
}
定义高、中、低档公共汽车
public class UpBus implements IBus{
}public class MidBus implements IBus{
}public class DnBus implements IBus{
}
(3)定义抽象工厂
public abstract class AbstractFactory {public abstract ICar createCar();public abstract IBus createBus();
}
(4)定义高档、中档、低档工厂
public class UpFactory extends AbstractFactory{@Overridepublic ICar createCar() {return new UpCar();}@Overridepublic IBus createBus() {return new UpBus();}
}
public class MidFactory extends AbstractFactory{@Overridepublic ICar createCar() {return new MidCar();}@Overridepublic IBus createBus() {return new MidBus();}
}
public class DnFactory extends AbstractFactory{@Overridepublic ICar createCar() {return new DnCar();}@Overridepublic IBus createBus() {return new DnBus();}
}
在Spring Boot框架中并不是哪里都使用了工厂模式,但是工厂模式确实被广泛地应用在Spring Boot中的一些关键组件中。以下是一些常见的使用工厂模式的Spring Boot组件:
-
BeanFactory和ApplicationContext接口:Spring Boot中的BeanFactory和ApplicationContext接口都是使用工厂模式的典型例子。它们充当了对象工厂的角色,负责创建和管理Bean实例。
-
RestTemplate类:RestTemplate类是一个非常流行的Spring Boot组件,它用于发送HTTP请求。RestTemplate使用工厂方法模式创建HTTP请求工厂实例,以便根据请求类型和其他配置创建合适的请求实例。
-
JdbcTemplate类:JdbcTemplate类是一个用于执行SQL查询和更新的Spring Boot组件。它使用工厂方法模式创建数据源和JDBC连接实例。
-
DispatcherServlet类:DispatcherServlet类是Spring Boot中的核心组件之一,用于处理HTTP请求和响应。它使用工厂方法模式创建HandlerMapping和HandlerAdapter实例,以便将请求路由到正确的处理程序方法并执行请求。
总之,Spring Boot框架中的许多组件都使用了工厂模式来创建和管理对象。这些组件可以更好地实现松耦合和可维护性,使得应用程序更加灵活和可扩展。
对于BeanFactory:
BeanFactory 是 Spring 框架中的一个关键接口,它使用工厂模式来创建和管理 Bean 实例。在 Spring Boot 中,BeanFactory 是 ApplicationContext 接口的父接口,也就是 ApplicationContext 继承了 BeanFactory 接口,因此 ApplicationContext 也是一个工厂模式的实现。
在使用 Spring Boot 框架时,我们通常会通过配置文件(比如 XML 配置文件、Java 配置类等)来定义 Bean,然后通过 BeanFactory 来获取 Bean 的实例。BeanFactory 的实现类可以根据配置文件中定义的信息创建对应的 Bean 实例,而且还可以对 Bean 的生命周期进行管理。
在 Spring Boot 中,我们通常使用如下方式来获取 BeanFactory 的实例:
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;public class MyBeanFactoryExample {public static void main(String[] args) {// 通过 ClassPathResource 加载配置文件ClassPathResource resource = new ClassPathResource("applicationContext.xml");// 创建 XmlBeanFactory 实例BeanFactory factory = new XmlBeanFactory(resource);// 通过 BeanFactory 获取指定名称的 Bean 实例MyBean myBean = (MyBean)factory.getBean("myBean");myBean.sayHello();}
}
在上面的代码中,我们首先使用 ClassPathResource 类加载了一个名为 applicationContext.xml 的配置文件,然后创建了一个 XmlBeanFactory 实例,最后通过 getBean() 方法获取了一个名为 myBean 的 Bean 实例,并调用了它的 sayHello() 方法。
总的来说,BeanFactory 接口是 Spring 框架中最基本的工厂模式实现,它用于创建和管理 Bean 实例,而且非常灵活、可扩展。如果需要更高级的功能(比如自动注入、AOP 等),可以使用 ApplicationContext 接口,它是 BeanFactory 接口的扩展,同时也是一个更加高级的工厂模式实现。
相关文章:
Java设计模式(二)——工厂模式
当用户需要一个类的子类实例,且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时,可采用工厂模式;当用户需要系统提供多个对象,且希望和创建对象的类解耦时,可采用抽象工厂模式。 工厂模式一般分为简单工厂、…...
【Maven】
MavenMaven简介仓库坐标Maven项目构建依赖管理生命周期及插件插件模块拆分与开发聚合继承属性版本管理资源配置多环境开发配置跳过测试私服Maven简介 Maven的本质时一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM) POM(Project Object Model)&a…...
[JAVA]继承
目录 1.继承的概念 2.继承的语法 3.父类成员访问 3.1子类中访问父类成员变量 3.2子类中访问父类成员方法 4.super关键字 5.子类构造方法 6.继承方式 7.final关键字和类的关系 面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复…...
Vue3 pinia持久化存储(组合式Api案例演示)
pinia-plugin-persist( pinia持久化插件) 本文采用的是 组合式Api的方式来做Pinia的持久化存储演示 如果对pinia的持久化还是不是很了解的👨🎓|👩🎓,可以看一下笔者的上一篇文章…...
8个你一看就觉得很棒的Vue开发技巧
1.路由参数解耦 通常在组件中使用路由参数,大多数人会做以下事情。 export default {methods: {getParamsId() {return this.$route.params.id}} }在组件中使用 $route 会导致与其相应路由的高度耦合,通过将其限制为某些 URL 来限制组件的灵活性。 正…...
vue3+ts 开发效率提升
1、vite pnpm项目初始化 pnpm: 比npm或yarn快10倍 pnpm与其他包管理器(如npm和Yarn)的不同之处在于它使用一种称为“硬链接”的独特安装方法。当你使用PNPM安装一个包时,它并不会将包的文件复制到每个项目的node_modules目录中&a…...
【数据结构与算法】队列和栈的相互实现以及循环队列
目录🌔一.用队列实现栈🌙1.题目描述🌙2.思路分析🌙3.代码实现⛈二.用栈实现队列☔1.题目描述☔2.思路分析☔3.代码实现🌈三.实现循环队列🌔一.用队列实现栈 🌙1.题目描述 我们先看一下题目链接…...
mysql连接不上问题解决
公司新搭内网测试环境,mysql远程登录问题解决 远程登录: 1 修改host, mysql> select user,host,plugin from user; ---------------------------------------------------- | user | host | plugin | ------------------------…...
利用nginx实现动静分离的负载均衡集群实战
前言 大家好,我是沐风晓月,今天我们利用nginx来作为负载,实现两台apache服务器的动静分离集群实战; 本文收录于沐风晓月的专栏《linux基本功-系统服务实战》,更多内容可以关注我的博客: https://blog.csd…...
与chatGPT神聊,引领你深入浅出系统调用
在操作系统的教学中,系统调用的作用不言而喻,但是,对系统调用常常是雾里看花,似乎明白,又难以真正的触及,即使在代码中调用了系统调用,比如调用fork()创建进程࿰…...
自学大数据第十天~Hbase
随着数据量的增多,数据的类型也不像原来那样都是结构化数据,还有非结构化数据; Hbase时google 的bigtable的开源实现, BigtableHbase文件存储系统GFSHDFS海量数据处理MRMR协同管理服务chubbyzookeeper虽然有了HDFS和MR,但是对于数据的实时处理是比较困难的,没有办法应对数据的…...
vue更高效的工具-vite
目录 1.webpack 2.vite是什么 3.使用vite创建项目 4.最后总结 🐼webpack 简单来说,Webpack是一个打包工具。 站在2018年的角度,成为一个优秀的前端工程师,除了要会写页面样式和动态效果之外,还需要会用主流的单页…...
HFish蜜罐的介绍和简单测试(一)
目录 0、什么是蜜罐 0.1、蜜罐的定义 0.2、蜜罐的优势 0.3、蜜罐与情报 1、HFish介绍 1.1、设计理念 1.2、HFish架构 1.3、HFish特点 1.4、常见蜜罐场景 2、快速部署 2.1、环境要求 2.2、联网环境,一键安装 2.3、安装效果 3、错误排查 3.1、管理端问题…...
2023面试题汇总二
一、CSS面试题 1. 清除浮动的方式有哪些? 为什么要清除浮动?因为浮动的盒子脱离标准流,如果父盒子没有设置高度的话,下面的盒子就会撑上来。 额外标签法(在最后一个浮动标签后,新加一个标签,给其设置cle…...
C# 支付宝接口在线收款退款
收款 在C#中使用支付宝在线支付功能,需要使用支付宝开放平台提供的SDK(软件开发工具包),通过SDK中提供的API(应用程序接口)实现在线支付功能。 以下是使用C#实现支付宝在线支付的大致步骤: 获…...
python例程:《企业编码生成系统》程序
目录《企业编码生成系统》程序使用说明主要代码演示源码及说明文档下载路径《企业编码生成系统》程序使用说明 在PyCharm中运行《企业编码生成系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时,只需…...
基于EB工具的TC3xx_MCAL配置开发04_ADC模块软件触发Demo配置
目录 1.概述2. EB配置2.1 添加HwUnit2.2 AdcPrescale配置2.3 添加ADC通道2.4 添加Adc Group2.5 Adc Group配置2.5.1 AdcGroup->General2.5.2 AdcGroup->AdcNotification2.5.3 AdcGroup->AdcGroupDefinition2.5.4 AdcGroup->AdcResRegDefinition2.6 中断配置1.概述 …...
内存操作函数
前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨未来…...
免费搭建个人博客
免费搭建个人博客,并发布到公网 利用hexo搭建个人博客,通过gitee的pages发布到公网 1 前置准备 安装git、安装node.js(尽量选择长期支持的版本) node.js官网:https://nodejs.org/en/ git官网:https://git-scm.com/book/zh/v2 安装…...
【Vue全家桶】详解Vue Router(一)
【Vue全家桶】Vue Router详解(一) Vue系列文章目录: 内容参考链接Vue(一)【Vue全家桶】邂逅Vue、Vue的多种引入方式Vue(二)【Vue全家桶】声明式编程、MVVMVue(三)【Vue…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
