Spring框架用的设计模式
单例模式
把类的构造函数私有化,通过get方法得到,且只允许有一个类的实例对象。
双重锁机制实现。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
为什么要加入volatile关键字,防止 singleton = new Singleton()->
a.分配 Singleton对象的内存空间
b.初始化对象
c.singleton设置它指向对象的地址。
指令重排序,a->b->c,线程A执行完ac,线程B判断if (singleton == null)就回直接返回一个没有对象的地址。所以要加入volatile防止重排序。
工厂模式
1.简单工厂:生产梨,生产苹果,都交给一个工厂来操作。
2.工厂方法:生产梨,梨工厂;生产苹果,苹果工厂。
3.抽象工厂,梨工厂和苹果工厂都继承一个抽象工厂,方便代码扩展。(这个spring没用到)
实际上抽象工厂模式主要用于替换一系列方法。例如将程序中的 SQL Server 数据库整个替换为 Access 数据库,使用抽象方法模式的话,只需在 IFactory 接口中定义好增删改查四个方法,让 SQLFactory 和 AccessFactory 实现此接口,调用时直接使用 IFactory 中的抽象方法即可,调用者无需知道使用的什么数据库,我们就可以非常方便的整个替换程序的数据库,并且让客户端毫不知情。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-07H3oz2a-1639208007393)(C:\Users\57281\AppData\Roaming\Typora\typora-user-images\image-20210621154640603.png)]
适配器模式
即A接口变成B接口。
class A{
void run(){
sout(i am A);
}
}
实现方式:1.适配器继承B类。
Class BAdapter extends A implement A{
void run(){
super.run();
}
}
2.将A实例 传入BAdapter 类中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0mqufMUT-1639208007396)(C:\Users\57281\AppData\Roaming\Typora\typora-user-images\image-20210822142752540.png)]
在线程池ThreadPoolExecutor中execute(Runalble runable)需要Runalble 对象,而submit(Callable task)将callable通过newTaskFor方法适配成RunnableFuture对象了,RunnableFuture他继承了Runalble 接口
将具有相关性但是不匹配的接口,通过适配器使其匹配。例如充电器(适配器)将220v家用电转化为5v给手机充电。
应用:spring Aop中,定义拦截器的Interceptor。
不是所以类都实现了一个接口,例如AspectJAfterReturningAdvice和AspectJMethodBeforeAdvice没有实现MethodInterceptor接口,而Spring Aop的方法拦截器却必须是实现了MethodInterceptor的。所以使用适配器MethodBeforeAdviceAdapter,该类使用MethodBeforeAdviceInterceptor(继承自MethodInterceptor)将其转化为MethodInterceptor,转化为拦截器的方法进行方法拦截,对方法进行增强。
MethodBeforeAdviceInterceptor继承了MethodInterceptor作为了一个适配器内部委托请求给MethodBeforeAdvice。
装饰者模式
继承的一个替代方案,实现相同的接口,对原有的方法增强和扩展,还可以新增功能。
新增功能:称之为半透明装饰模式。
透明,看不见,不需要知道内部实现,这里是不需要知道,开发人员不需要知道被装饰的方法。
不透明:看见,开发人员需要知道具体的装饰类和扩展的功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r6CxfzGd-1639208007397)(C:\Users\57281\AppData\Roaming\Typora\typora-user-images\image-20210621191244695.png)]
装饰类主要起到锦上添花的功能,例如:DateInputStream用于更加方便的读取int,double类型
观察者模式
观察者和被观察者,通常为一对多关系,即多个观察者,一旦被观察执行预期的事件,通知所有观察者。
在spring中的应用:事件和事件监听器
1.定义事件(被观察者):实现一个类继承ApplicationEvenet类。
2.定义事件监听者(观察者):实现ApplicationLister。重写onApplicationEvent()响应事件。
3.发布事件,可以通过ApplicationEventPublisher 的 publishEvent() 方法发布消息。
策略模式
殊途同归,对于不同算法实现同一种功能,由客户端/开发人员选择具体的算法(策略)。例如,程序员选择不同的排序方法实现排序:冒泡、选择、快排等。
Spring 中Resource接口,是 Spring 资源访问策略的抽象,它本身并不提供任何资源访问实现,具体的资源访问由该接口的实现类完成 —— 每个实现类代表一种资源访问策略。
Spring 为 Resource 接口提供了如下实现类:
UrlResource:访问网络资源的实现类。
ClassPathResource:访问类加载路径里资源的实现类。
FileSystemResource:访问文件系统里资源的实现类。
ServletContextResource:访问相对于 ServletContext 路径里的资源的实现类:
InputStreamResource:访问输入流资源的实现类。
ByteArrayResource:访问字节数组资源的实现类。
这些 Resource 实现类,针对不同的的底层资源,提供了相应的资源访问逻辑,并提供便捷的包装,以利于客户端程序的资源访问。
rce:访问输入流资源的实现类。
ByteArrayResource:访问字节数组资源的实现类。
这些 Resource 实现类,针对不同的的底层资源,提供了相应的资源访问逻辑,并提供便捷的包装,以利于客户端程序的资源访问。
### 代理模式