前言:java一共有23种设计模式,其中常用的需要熟练掌握的大约有10种左右,剩余10几种了解即可,在合适的场景下使用设计模式不仅可以提供代码质量,对以后的代码维护和拓展也有很大好处.
目录
1.单例模式
https://blog.csdn.net/lovexiaotaozi/article/details/83896573
1.1什么是单例模式
单例模式要求一个对象最多只能有一个实例,要求单例类自己创建自己的唯一实例.
1.2单例模式的优势
可以避免一个全局适用的类被频繁的创建/销毁对象带来的资源开销
1.3单例模式的适用场景
想控制实例数量,节省资源,比如spring的bean默认就是单实例的.
1.4单例模式的饿汉式和懒汉式
饿汉式的实现,上来不管三七二十一,先创建实例,饿汉式实现相对简单,也不会存在线程安全的问题,平时使用一般都会采用饿汉式实现;懒汉式则默认不创建实例,只有当获取实例的方法被调用时才去判断是否要创建实例,如果实例不存在时创建才会创建,存在线程安全问题,需要加锁来保证全局唯一实例.
1.5懒汉式的double-check
懒汉式的实现,为了控制锁的粒度,最大限度的提高效率,通常会采取double-check方式进行创建,第一层判断是基于是否需要加锁的判断,第二层则是基于线程安全的判断:
if (obj == null){
synchronized (this){
if (obj == null){
obj = new Object();
}
//TODO
}
}
2.工厂模式
https://blog.csdn.net/lovexiaotaozi/article/details/83897121
2.1什么是工厂模式
工厂模式是采用统一接口创建对象的方式,调用方无需再关心对象如何被创建,只需要使用即可,它提供了一种对象的最佳创建方式,工厂模式在spring的bean工厂中有很好的体现.
2.2工厂模式的优势
能够对对象的使用方屏蔽对象创建的复杂度,降低代码的复杂度.
2.3工厂模式的适用场景
在能够明确在不同条件下需要创建不同的对象,且对象的创建逻辑相对复杂或代码量较大时,可以考虑采用工厂模式
2.4简单工厂模式和抽象工厂模式
简单工厂模式可以根据传入的条件动态的创建所需要的对象,当需要对象超出简单工厂所能创建的范围时,简单工厂就无能为力了;抽象工厂是对简单工厂的进一步抽象,是"工厂的工厂",可以应对对象创建的灵活多变性,符合代码的开闭原则,如果需要新增某种对象的创建范围,只需要新增几行创建该对象工厂的代码,不需要改原来代码.
3.责任链模式
https://blog.csdn.net/lovexiaotaozi/article/details/85247603
3.1什么是责任链模式
为请求创建一个可以处理该请求的处理链,将请求的发送和处理解耦,该请求会在处理链上传递,对应的请求处理者如果具备处理能力就处理请求,如果不能处理会沿着处理链传递给下一个处理者,这种设计模式在netty中有大量体现.
3.2责任链模式的优势
责任链模式可以将请求的发送方和处理方解耦,降低代码耦合度;
符合开闭原则,有新的处理逻辑无需改动原来代码;
提高代码可读性,避免大量的if-else
3.3责任链模式的适用场景
完成一件事情,需要多个处理者各司其职的场景,可以考虑使用责任链模式,避免代码种出现大量If-else
4.观察者模式
https://blog.csdn.net/lovexiaotaozi/article/details/85161368
4.1什么是观察者模式
当一个对象的状态发生改变时,需要通知其它关联对象,关联对象根据状态做出相应调整.
4.2观察者模式有什么优势
解耦,将观察者对象和被观察者对象之间解耦;
建立一套触发机制.
4.3观察者模式的适用场景
当一个对象的状态发生改变,需要影响到其它对象时,可以考虑采用观察者模式,比如订单的状态由未支付->已支付,积分模块需要增加相应积分,库存需要扣减等...
4.4观察者模式和订阅模式有什么区别
观察者模式是松和耦合的,订阅模式则是完全解耦的,因为观察者模式中只有观察者和被观察者两种类型的对象,被观察者状态的改变会直接通知到观察者,观察者和被观察者直接是有直接联系的,但订阅模式则多了一个第三方"中介",被观察者状态的改变是通过中介传达给观察者的.
5.代理模式
https://blog.csdn.net/lovexiaotaozi/article/details/83900959
5.1什么是代理模式
代理即通过代理对象访问目标对象,代理相当于中介,其中代理分为静态代理和动态代理,静态代理灵活性很差,开发中几乎不用.
5.2代理模式有什么优势
代理模式可以起到中介隔离的作用;
符合代码设计的开闭原则,可以通过代理类增强原有方法,而不需要改动原来方法.
5.3代理模式的适用场景
想在一个类的访问层作控制或者需要增强某个已存在的方法时可以考虑使用代理模式.
5.4jdk动态代理和cglib动态代理
jdk动态代理是Jdk提供的动态代理实现方式,要求被代理对象必须是接口,否则无法代理.
cglib动态代理则需要引入cglib库,要求被代理对象必须可以被继承,不能被final修饰,否则无法代理,底层是通过动态字节码生产被代理对象的子类完成代理,所以被代理对象不能被final修饰.
从性能来看,cglib动态代理的性能要高于jdk动态代理,两者各有适用场景,spring的aop底层正是基于这两种代理实现的.
6.原型模式
https://blog.csdn.net/lovexiaotaozi/article/details/84070502
6.1什么是原型模式
原型模式提供了一种创建对象最佳的方式,可以以较高的效率创建对象
6.2原型模式有什么优势
提高了对象创建的性能,避免构造函数的约束
6.3原型模式的适用场景
对对象创建性能要求较高,以及一个对象多个修改者的场景;
6.4浅拷贝,深拷贝区别
浅拷贝:实现Cloneable接口并重写clone方法,如果对象中存在对其它对象的引用,则无法完成对引用对象的正确拷贝.
深拷贝:拷贝通过Serializable读取二进制流实现,可以完成对对象及其引用对象的正确拷贝.
7.模板方法模式
https://blog.csdn.net/lovexiaotaozi/article/details/84136441
7.1什么是模板方法模式
将固定不变的方法在抽象父类中实现,将可变的部分交给子类去实现,父类定义了一套通用的模板,子类只需要照着这套模板去实现可变的部分即可.
7.2模板方法模式有什么优势
可以提高代码复用量,减少重复代码,抽取公共代码,方便维护
7.3模板方法模式的适用场景
某块功能的实现有固定的步骤,然后这部分功能中有一些是可变的,一些是不会变的,在这种场景下,可以考虑使用模板方法模式.
8.建造者模式
建造者模式可以自己手动实现,也可以通过lombok的@Builder注解快速实现(推荐)
8.1什么是建造者模式
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示. 这句话听上去很绕口,难以理解,按我的理解建造者模式就是用一种更为简单直观的方式来创建对象,让有多个构造参数的对象创建更为简单灵活,可以自由组合构造参数.
8.2建造者模式有什么优势
提高了代码的可读性和逼格
8.3建造者模式的适用场景
当一个类的构造参数超过4个,且这4个构造参数是可选的情况下,可以考虑使用建造者模式.
9.适配器模式
https://blog.csdn.net/lovexiaotaozi/article/details/84140637
9.1什么是适配器模式
将某个类的接口转换为客户希望的另外一个接口,让原本不能直接匹配的两个类可以协同工作,有点类似我们平时充电用的接口转换器.
9.2适配器模式的优势
可以将一些现存的类,经过简单适配后满足新的业务需求,符合开闭原则.
9.3适配器模式的适用场景
当原有系统中的类可以在新的业务场景下会被用到,但该类不能直接匹配新业务场景的接口,可以通过适配器进行转换,转换后可以复用原始类中的方法时,可以考虑用适配器模式.
10.策略模式
https://blog.csdn.net/lovexiaotaozi/article/details/84062227
10.1什么是策略模式
策略模式定义:一个类的行为或算法可以在运行时更改,听上去有点像多态,事实上其原理也就是通过接口实现的多态.
10.2策略模式有什么优势
减少代码中的If-else,提高代码可读性和可维护性,同时符合开闭原则.
10.3策略模式的适用场景
一个系统需要动态地在多种算法中切换,切换时需要通过某种逻辑控制时,可以考虑采用策略模式,减少代码中的If-else