1.工厂模式:Beanfactory和ApplicationContext
2.单例模式:bean的构建
3.代理模式:AOP
4.模板模式:jdbcTemplate,hibernateTemplate等以Template结尾的对数据库操作的类,一般情况下,是使用继承的方式来实现模板模式,但spring没有使用这种方式,而死使用Callback模式与模板方法模式配合,即达到了代码服饰的效果,同时增加了灵活性。
ps:
Spring中的Callback模式与Template模式合用,随处可见。Template method被广泛的使用,像Servlet就是使用这个模式。Template mothod模式虽然能简化很多重复的代码,但这种模式的也有不少限制。Template mothod将一个功能的实现分成许多小的步骤,在父类中定义了这些步骤的顺序,让子类来具体实现每一个小的步骤。这些小的步骤是protected,以防止用户不正确的使用这些小的步骤而产生异常。这样就产生了一个限制,那就是你需要继承Template然后重新实现具体的小步骤。如果这个Template有许多方法,就像JdbcTemplate,如果你每次继承这个庞大的类,然后只是重写某个小步骤中来订制你自己的功能,就会显得非常笨重,更何况数据库操作使用的如此频繁,难道你每进行一个操作就通过继承订制一个,显然不可能这么做。
至所以不完全采用Template的模式是因为Template很庞大,有许多方法,继承它的话划不来:显得笨重。
Spring使用Callback模式与之配合,达到了去掉重复代码的效果,同时增加了很大的灵活性,你只需要实现某些CallBack就可轻松订制出Template。
那么什么时候才是Callback模式与Template模式结合的最佳时机呢?显然如果每个具体的步骤都需要真正去具体实现而不是简单的改变参数或设置某个对象就ok的话,使用Callback很难去订制,因为你可能需要传递多个Callback作为参数,并让用户去实现,是用Java的内部类本来就是一个比较丑陋的语法,更何况参数是多个。这相当于你把每个小步骤封装成为接口,然后分别继承之然后实现。显然没有达到方便灵活的效果,这时候直接使用Template method模式就比结合Callback要好。而如果用户只需要定制一个方法能就达到用户的要求,或者更简单,只是设置不同的参数,那么使用Callback就具有很好的灵活性。
使用Template-Callback模式的时机:用户只需要定制一两个方法就能达到要求或只需要设置不同的参数。
Template-Callback模式在Spring中的实现步骤:
1. 创建一个Template对象: jdbcTemplate = new JdbcTemplate(dataSource);
2. 该Template有个execute方法,里面含有需要你传递进来的参数(参数声明可能是接口,也可能是具体类).该方法已经实现了你需要的达到目的的步骤,以及会返回你所需要的东西。你所要做的就是实现该方法所需要的参数。
3. 创建参数并调用Template方法。你可能需要实现接口来创建Template方法所需要的参数(可能采取内部类的形式)。
该模式如何体现了CallBack????
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回, 它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。
5.观察者模式:是一种对象行为型模式。它表示的是一种对象与对象之江具有依赖关系。当一个对象发生变化的时候,这个对象所以来的对象也会做出反应。Spring事件驱动模型就是观察者模式很经典的一个应用。Spring事件驱动模型非常游泳,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
6.适配器模式:将一个接口转换成客户希望的另一个接口,适配器模式使接口不佳弄的哪些类可以一起工作,泣别面馆为包装器(Wrapper)。
1)spring AOP的增强或者通知(Advice)使用到了适配器模式,与之相关的接口AdvisorAdapter。Advice常用的类型有:BeforeAdvice(目标方法调用前置通知),AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice
(目标方法执行结束后,return之前)等等。每个类型Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptor
、AfterReturningAdviceAdapter
、AfterReturningAdviceInterceptor
。Spring预定义的通知要通过对应的适配器,适配成 MethodInterceptor
接口(方法拦截器)类型的对象(如:MethodBeforeAdviceInterceptor
负责适配 MethodBeforeAdvice
)。
2)SpringMvc中,DispatherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。解析到对应的Handler(也就是我们平常说的Controller控制器)后,开始由HandlerAdapter适配器处理。HandlerAdapter作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller作为需要适配的类。
为什么要在Spring MVC中使用适配器模式?
Spring MVC中的Controller种类众多,不同类型的Controller通过不同的方法来对请求进行处理。如果不利用适配器模式的话,DispacherServlet直接获取对应类型的Controller,需要自行来判断像下面这段代码一样:
if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanceof XXX){ ... }else if(...){ ... }
假如我们再增加一个 Controller
类型就要在上面代码中再加入一行 判断语句,这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 – 对扩展开放,对修改关闭。
7.装饰者模式:可以动态地给对象添加一些额外的属性或者行为。相比于使用继承,装饰者模式更加灵活。简而言之,当我们需要修改原有的功能,但我们又不愿直接去修改原有的代码时,设计一个Decorator套在原有代码外面。其实在JDK中就有很多地方用到了装饰者模式,比如InputStream家族,InputStream类下有FileInputStream(读取文件),BufferedInputStream(增加缓存,时读取文件速度大大提升)等子类都不在不修改InputStream代码的情况下扩展了它的功能。
Spring中配置DataSource的时候,DataSource可能时不同的数据库和数据源。我们能否根据客户的需求
在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式(这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有 Wrapper
或者 Decorator
。这些类基本上都是动态地给一个对象添加一些额外的职责
总结
Spring 框架中用到了哪些设计模式?
- 工厂设计模式 : Spring使用工厂模式通过
BeanFactory
、ApplicationContext
创建 bean 对象。 - 代理设计模式 : Spring AOP 功能的实现。
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 模板方法模式 : Spring 中
jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 - 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
- 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配
Controller
。 - ......
原文地址:https://www.cnblogs.com/bierenbiewo11/p/11290601.html