Spring用了哪些设计模式?
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。总共有 23 种设计模式
使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
Spring用了哪些设计模式?
1)单例模式: 在Spring中定义的bean默认是单例模式。
2)工厂模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建Bean对象。
3)代理模式:Spring AOP功能的实现是通过代理模式中的动态代理实现的。
4)策略模式:Spring中资源访问接口Resource的设计是一种典型的策略模式。Resource接口是所有资源访问类所实现的接口,Resource 接口就代表资源访问策略,但具体采用哪种策略实现,Resource 接口并不理会。客户端程序只和 Resource 接口耦合,并不知道底层采用何种资源访问策略,这样客户端程序可以在不同的资源访问策略之间自由切换。
5)适配器模式:Spring AOP的增强或通知使用到了适配器模式。SpringMVC中也是用到了适配器模式适配Controller。
6)装饰器模式:Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源,项目需要连接多个数据库,这种模式让我们可以根据客户需求切换不同的数据源。
7)模板模式:Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,就是用到了模板模式。
8)观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
分析:
单例模式
如果一个全局使用的类需要频繁地创建与销毁,那么我们可以用单例模式来减少了内存的开销。
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件
显然单例模式的要点有三个;一单例类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中含有一个该类的静态私有对象,三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
//要点一:单例类只能有一个实例。 //单例模式的类只提供私有的构造函数,这样该类就不会被实例化 private SingleObject(){} //要点二:单例类必须自己创建自己的唯一实例。 //创建一个该类的静态私有对象 private static SingleObject instance = new SingleObject(); //要点三:单例类必须自行向整个系统提供这个实例。 //提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象 public static SingleObject getInstance(){ return instance; }
适配器模式
如果需要让任何两个没有关联的类一起运行,提高类的复用性和透明性,灵活性,那么可以用适配器模式,举个实例,TF卡插入读卡器可以转换成SD卡,此时读卡器就作为内存卡和笔记本之间的适配器。
举代码实例,笔记本通过读卡去读取TF卡
https://www.runoob.com/design-pattern/adapter-pattern.html
在这种模式下,计算机并不需要知道具体是什么卡,只需要负责操作接口即可,具体操作的什么类,由适配器决定。
装饰器模式
一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。如果我们在不想增加很多子类的情况下扩展类,那么就可以用装饰器模式。
策略模式
策略模式,一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
优点: (1)使用策略模式可以避免使用多重条件判断,(2)扩展性良好
缺点:(1)策略类会增多。(2)所有策略类都需要对外暴露
项目实战:
WKD项目中导出模板中使用到了。
观察者模式
观察者模式属于行为型模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。
优点:
1、观察者和被观察者是抽象耦合的,提高了应用程序的可维护性和重用性。
2、建立一套触发机制。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
4、Java中的消息的通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。
使用场景:
1、当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2、当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。
3、当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的
参考:
https://www.runoob.com/design-pattern/design-pattern-tutorial.html