浅谈Spring框架应用的设计模式(一)——工厂模式

2023-11-13

前言

Spring是目前Java企业级开发应用广泛的框架之一,其具有强大的生态,且得益于其提供的高扩展能力,能够减少开发成本,提高开发效率。如此优秀的框架,当然离不开各种设计模式,本文主要介绍设计模式中的工厂模式在Spring框架中的应用。


一、工厂模式介绍

工厂模式属于三种设计模式分类中的创建者模式。工厂模式主要是将创建对象的过程交给工厂进行处理,通过工厂提供给我们需要创建的对象,而不用自己直接去进行对象的创建。工厂模式包括三种:简单工厂模式(其不符合设计模式的开闭原则,不属于23中设计模式之一)、工厂方法模式以及抽象工厂模式,下面对每个模式进行逐一介绍。

1、简单工厂模式

“简单”,从名字中便可以知道,其是实现了工厂模式最简单的方案,大致可以分为以下二类:

(1)静态工厂模式

在创建方法中根据需要返回相对应的对象,当然,有新增对象的时候,需要修改方法,这样便会破坏开闭原则。下面用代码举个例子。

	//电脑产品
	public class Computer{
	}
	//Asus电脑
	public class AsusComputer extends Computer{
	}
	//Dell电脑
	public class DellComputer extends Computer{
	}
	//电脑创建工厂
	public class ComputerFactory{
	  public enum ComputerType{
	  	ASUS,DELL;
	  }
	  //创建方法:当有新的电脑产品的增加时,需要在create方法中进行添加
	  static Computer create(ComputerType computerType){
	  	if(computerType.equals(ComputerType.ASUS)){
	  		return new AsusComputer();
	  	}
	  	if(computerType.equals(ComputerType.DELL)){
	  		return new DellComputer();
	  	}else{
	  		return null;
	  	}
	  }
	}

(2)利用反射机制实现的简单工厂

由于静态工厂模式会破坏开闭原则,因此,从静态工厂模式扩展出一种利用反射可以动态添加创建对象的简单工厂模式。通过新对象注册到容器中,并利用反射机制来实现对象的创建,从而不用修改代码,不会违背开闭原则。还是以电脑产品为例子,来看下其实现。

	//电脑产品
	public class Computer{
	}
	//Asus电脑
	public class AsusComputer extends Computer{
	}
	//Dell电脑
	public class DellComputer extends Computer{
	}
	//电脑创建工厂
	public class ComputerFactory{
	   //注册容器
	   private static Map<String,Class<? extends Computer>> computerContext = new ConcurrentHashMap<>();
	   //注册电脑类型
	   static void registerComputer(String computerType,Class<? extends Computer> cls){
	   		computerContext.put(computerType,cls);
	   }
	  //创建方法:当有新的电脑产品的增加时,可以通过registerComputer方法将产品注册进来,不用改变代码
	    static Computer create(String computerType){
	        Computer needComputer = computerContext.get(computerType).newInstance();
	  		if(needComputer != null){
	  			return needComputer;
	  		}else{
	  			return null;
	  		}
	  }
	}

简单工厂模式,不够抽象,耦合度高,虽然可以利用反射机制来解决静态工厂模式的弊端,但是需要使用注册空间以及反射,在创建对象量大的场景下会降低效率,因此,便会有工厂方法模式来解决这些弊端。

2、工厂方法模式

工厂方法模式是简单工厂模式基础上的变形,当需要新增新对象时,只需要实现相对应的工厂接口方法来创建对象,无需修改工厂代码,从而符合开闭原则。

	//电脑产品
	public class Computer{
	}
	//Asus电脑
	public class AsusComputer extends Computer{
	}
	//Dell电脑
	public class DellComputer extends Computer{
	}
	//电脑创建工厂接口
	public interface ComputerFactory{
	  public Computer createComputer();
	}
	//AsusComputer创建工厂
	public class AsusComputerFactory implements ComputerFactory {
	  	public Computer createComputer(){
	  		return new AsusComputer();
	  	}
	}
	
	//DellComputer创建工厂
	public class DellComputerFactory implements ComputerFactory {
	  	public Computer createComputer(){
	  		return new DellComputer();
	  	}
	}
	//...需要创建更多对象时,去实现ComputerFactory接口即可,这样即降低了耦合度,又不违背开闭原则

工厂方法模式,降低了耦合度,提高扩展性,符合开闭原则,但是其存在一个问题,即仅仅只能在同一个维度上进行对象的创建,这样也就引出了抽象工厂模式。

3、抽象工厂模式

抽象工厂模式,可以认为是工厂方法模式的增强版,其提供了多种对象的创建方法,使得工厂方法模式可以在不同维度上进行不同对象的创建。

	//电脑产品
	public class Computer{
	}
	//Asus电脑
	public class AsusComputer extends Computer{
	}
	//Dell电脑
	public class DellComputer extends Computer{
	}
	//服务器产品
	public class Server{
	}
	//Asus服务器
	public class AsusServer extends Server{
	}
	//Dell服务器
	public class DellServer extends Server{
	}
	
	//创建工厂接口
	public interface Factory{
	  public Computer createComputer();
	  public Server createServer();
	}
	//Asus创建工厂
	public class AsusFactory implements Factory{
	  	public Computer createComputer(){
	  		return new AsusComputer();
	  	}
	  	 public Server createServer(){
	  	 	return new AsusServer(); 
		 }
	}
	//Dell创建工厂
	public class DellFactory implements Factory {
	  	public Computer createComputer(){
	  		return new DellComputer();
	  	}
	  	 public Server createServer(){
	  	 	return new DellServer(); 
		 }
	}

有了抽象工厂模式,便可以在多个维度进行对象的创建,减少了工厂方法对象创建的单一性。

二、Spring框架中工厂模式的重要应用

上面简单介绍了工厂模式的三种类型,接下来我们就来看看Spring框架中有哪些地方运用到了工厂模式吧。

1、BeanFactory

相信大家都对BeanFactory不陌生,直接翻译就是Bean工厂。Spring框架的两个关键就是IOC和AOP,其中IOC的设计当然就涉及到BeanFactory;有了Spring框架,我们就很少自己进行对象的创建了,而我们使用到的对象当然就是交给Spring的工厂模式来创建的了。其中BeanFactory是Spring容器的顶层接口,也是Bean工厂最上层的接口,其会有很多工厂实现例如,我们可以把BeanFactory看成是一种工厂方法模式。
BeanFactory结构及其实现
从BeanFactory接口的结构我们可以看出,通过getBean重载方法,为我们创建不同的Bean对象,当然其也有很多工厂实现,例如我们用的最多的DefaultListableBeanFactory,还有SimpleJndiBeanFactory、StaticListableBeanFactory等等。Spring工厂模式的应用还加入了反射及配置。通过对各种配置,例如xml,注解等等解析成BeanDefinition,然后根据不同工厂要求通过反射创建不同的Bean对象,这样开发过程中,我们可以将需要创建的对象通过配置等方式交给Bean工厂去完成,使用时直接获取便可。Bean工厂的设计,大大降低耦合度,并增强可扩展性,提高了代码的可维护性,符合设计模式的原则。

2、FactoryBean

讲完BeanFactory,再介绍另外一个工厂模式的应用FactoryBean,想必大家也经常会比较这俩。实际上,这两个接口都是用于创建对象,都可以看做是工厂方法模式的实现。BeanFactory是Spring的一个大工厂,创建着Spring框架运行过程中所需要的Bean;而FactoryBean是一个定制化工厂,其会存在于BeanFactory创建对象的过程中,当有需要时,会通过FactoryBean去自定制个性化的Bean,从而Spring框架提高扩展能力。
FactoryBean结构及其实现
FactoryBean工厂通过getObject()方法来创建并返回对象,我们可以通过实现FactoryBean来定制化自己需要的Bean对象,因此,FactoryBean是一种典型的工厂方法模式的实现。
我们在引入其他框架整合Spring时,便会有很多桥接整合包,例如mybatis-spring等,其中就会有FactoryBean的实现,例如SqlSessionFactoryBean、MapperFactoryBean等,将需要整合的定制化Bean通过工厂方法的模式,加入进Spring容器中,从而大大降低了耦合程度,也为开发提供了扩展能力。

//FactoryBean接口
public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

	//对象创建方法,不同的对象去实现不同的FactoryBean工厂,通过工厂方法模式来实现Bean的定制化
	@Nullable
	T getObject() throws Exception;

	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}
}

总结

本文主要针对工厂模式的分类和实现进行了讲解,并对Spring框架中两个重要工厂模式的实现BeanFactory和FactoryBean进行了介绍,工厂模式的实现是Spring管理Bean对象的基础,也是Spring框架解耦和重要的扩展点。BeanFactory以及FactoryBean可以看做是工厂方法模式的实现,BeanFactory融合了反射以及配置,提高了工厂创建对象的灵活程度,FactoryBean为BeanFactory创建的对象提供了定制化的对象工厂实现,也能够提高Spring创建和管理对象的能力。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈Spring框架应用的设计模式(一)——工厂模式 的相关文章

随机推荐

  • pytorch:线性回归(Regression)

    使用pytorch python实现回归 程序 import torch import torch nn functional as F from matplotlib import pyplot as plt 创建数据 x torch u
  • Jtest简介

    Jtest是一个集成的 易于使用和Java单元测试工具 它能够自动测试任何Java类 JSP或部件 而不需要你编写一个测试用例 测试驱动程序和测试桩 只需一键 Jtest自动测试代码的构造 白盒测试 代码功能 黑盒测试 并维护代码的完整性
  • caffe convert_image 初略解析

    需要的基础知识 OpenCV 建议去看官网的图文教程 LevelDB http dblab cs toronto edu courses 443 2014 tutorials leveldb html 这个是我学习的教程 今天在看caffe
  • 时序预测

    时序预测 MATLAB实现贝叶斯优化LSTM时间序列预测 BO LSTM 预测效果 基本介绍 相对于模型的参数而言 Parameter 我们知道机器学习其实就是机器通过某种算法学习数据的计算过程 通过学习得到的模型本质上是一些列数字 如树模
  • uni-app富文本渲染方案rich-text、uparse、v-html简单解析

    uniapp语法 rich text 1 rich text是uni app的内置组件 提供了高性能的富文本渲染模式 2 API参考https uniapp dcloud io component rich text 3 rich text
  • 基于PHP的旅游管理系统

    系列文章目录 基于SpringBoot的高校在线答疑管理系统 基于SpringBoot的外卖点餐管理系统 基于SpringBoot的实验室管理系统 目录 系列文章目录 前言 一 相关技术 二 系统设计 1 系统体系结构 2 数据库设计原则
  • [人工智能-数学基础-1]:深度学习中的数学地图:计算机、数学、数值计算、数值分析、数值计算、微分、积分、概率、统计.....

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119710145 目录 1 为
  • java基础面试题系列(101-112)[完结撒花]

    20200718 by 1z 请说明sleep 和 wait 有什么区别 1 sleep 是Thread的成员方法而Wait 是Object的成员方法 2 sleep 没有释放锁 因此在sleep结束后依旧是原线程执行 而wait 释放了锁
  • pytorch(11)-- crnn 车牌端到端识别

    车牌图片端到端识别 一 前言 二 数据集处理 三 crnn模型文件 四 训练验证代码 五 测试代码 六 代码搬自 一 前言 本文主要记录了使用crnn 对车牌图片做端到端识别 即不用对车牌字符做逐个字符分割识别 车牌第一个字符为汉字 共有3
  • JS的map()方法会改变原始数组吗?

    map 为操作数组的一种方法 官方文档显示 map 方法返回一个新数组 数组中的元素为原始数组元素调用函数处理后的值 map 方法按照原始数组元素顺序依次处理元素 注意 map 不会对空数组进行检测 注意 map 不会改变原始数组 但是我在
  • kali 更新无法引导启动Windows11的解决办法

    摘要 出现的问题描述 更新kali之后 在你的Grub2引导中 没有Windows11的选项 但是通EFI引导是能正常启动系统的 保证Windows11的默认引导项是没有损坏 一 验证操作系统引导项 1 ls 在开机后的Grub引导页面 按
  • Unity 的 mathf.lerp

    Unity 的mathf lerp float a float b float t 是线性插值函数 a b的顺序很重要 如果a 10 b 0 则说明是从10到0的变化 如果是a 0 b 10 则说明是从0向10的变化 t的范围在0 1之间
  • Tomcat 8安装

    https www linuxidc com Linux 2017 10 147773 htm 前提 必须正确安装JDK 一 通过二进制包 tar gz 安装 下载 https mirrors tuna tsinghua edu cn ap
  • 分布式数据库需要考虑的(BigTable VS Dynamo)

    分布式数据库需要考虑的 BigTable VS Dynamo 在设计 评价分布式数据库的时候需要考虑一些最基本的特性 我想这些特性可能包括 1 存储系统 一种是类似BigTable将存储交给GFS去做 GFS会保证写入数据的完整 另外一种是
  • 应用多元统计分析(题解)

    题目 应用多元统计分析 北京大学出版社 第四章 回归分析 习题4 3 具体题目见下图 第一小问解答
  • Halcon深度学习常见问题及解决方法

    一 常见问题及解决办法 1 set dl model param DLModelHandle gpu GpuId GpuId 0 选中第一块显卡做深度学习训练 GpuId 1 选中第二块显卡做深度学习训练 类推 查询可用多显卡信息 quer
  • 使用EasyExce实现Excel文件解析

    hello 你好呀 我是灰小猿 一个超会写bug的程序猿 在上一篇文章中我和大家简单的介绍了使用easyexcel技术在有对象和无对象情况下实现Excel文件的写入操作 那么今天这一篇文章 我就继续来和大家讲一下 使用easyexcel技术
  • 入门力扣自学笔记211 C++ (题目编号:1781)

    1781 所有子字符串美丽值之和 题目 一个字符串的 美丽值 定义为 出现频率最高字符与出现频率最低字符的出现次数之差 比方说 abaacc 的美丽值为 3 1 2 给你一个字符串 s 请你返回它所有子字符串的 美丽值 之和 示例 1 输入
  • Football数据集可视化处理——gephi可视化处理数据

    1 football数据集的文件格式 根据如图所示football数据集和的文件格式如下所示 下图表示football数据集节点部分信息 下图表示football数据集边的部分信息 根据上述两个图中的格式对football数据集的格式介绍可
  • 浅谈Spring框架应用的设计模式(一)——工厂模式

    文章目录 前言 一 工厂模式介绍 1 简单工厂模式 1 静态工厂模式 2 利用反射机制实现的简单工厂 2 工厂方法模式 3 抽象工厂模式 二 Spring框架中工厂模式的重要应用 1 BeanFactory 2 FactoryBean 总结