Fork me on GitHub

大战设计模式(第二季)【5】———— 从源码看适配器模式

前言

对于很多设计模式都是后期优化,或者是后期版本迭代,为了适应原来的业务进行扩展的时候使用的,适配器模式就是其中的一种。适配器模式其实很容易理解,就和名字一样它就是一个适配器,将原本两个无法调用和兼容的类通过它就能行。类似生活中很多的电源适配器或者是转接口等。

适配器模式基础:https://www.cnblogs.com/linkstar/p/7710687.html

 

从SpringMVC来看适配器模式

因为适配器模式比较简单,所以用一个最复杂的实际源码中的案例来解释他。那就是SpringMVC。要理解这里的整体实现和原因就必须要了解整个过程,让我们慢慢来看。


这边借用网上的一张图来说明请求过程,如果你对SpringMVC熟悉,那么这张图应该烂熟于心了。这边主要理解适配器模式,所以不赘述过多的其他细节。首先我们来看最重要的DispatcherServlet这个类。

所有用户发起的请求都会通过DispatcherServlet来处理。其中最主要的方法就是doDispatch

这里用红框标出来的,可以看到注释说明了,通过当前的请求确定是那个handler来处理,有兴趣的同学可以继续往里看,里面写的是,如果通过请求的地址得到对应的handler也就是图中画的HandleMapping

接着下面就是我们的适配器登场了

可以从注释看到,通过请求来获得对应的适配器。注意这里传入的参数是刚才获得的handler

然后方法进去,我们就很明显可以看到了,通过循环去确定使用哪个适配器,看当前适配器是否支持handler如果支持就返回。
然后我们来看看适配器接口HandlerAdapter的所有实现

可以看到有各种各样的适配器,其中我们看一个最常见的

还记得刚才的supports方法吗?这边可以看到,如果是controller的话,这边的处理就会采用这个适配器,因为这个适配器是支持处理controller的。然后注意这里的handle方法就是我们实际的处理方法了,这里最终会调用handleRequest方法,而handleRequest是controller接口的一个方法,这个方法最终我们会返回ModelAndView,也就是我们流程图中所看见的第三个过程。

这个过程可能有点奇怪,也有点复杂,你需要仔细琢磨和体会。这也是我为什么使用这个例子的原因。

总结一下,我们的controller是被适配者,通过适配器来适配了请求从而将请求通过controller来进行处理。

 

最关键的来了

我们从整个过程中可以看到,其实说实在的好像对于我们来说没有什么意义,就只是多了一个适配器而已,为什么spring要这么设计呢?这样设计的理由和好处是什么呢?这才是我们学习设计模式的关键。
那么为啥呢?

其实从这张图我们就可以看出一些端倪,为什么会有这些适配器呢?因为最终进行请求处理的方式是不一样的,举个例子,比如普通的servlet和controller处理请求就是不一样的,servlet是通过service方法进行请求处理的,而controller是通过handleRequest方法进行请求处理的,处理返回的结果也是不同的,servlet内部已经处理完了对于view的,而controller后面需要一个ModelAndView而进行后续的处理。如下图对比所示:

所以为了兼容原来的servlet,那么就需要使用适配器来作为中间的一个纽带,来包容各种处理请求的方式,也方便后续的扩展,说白了,如果后续spring想重新做一个类似controller的类来处理请求也很容易了,原来使用controller的地方也不会受到影响,这就是设计模式的开闭原则,对修改关闭,对扩展开。

你仔细体会一下,就会发现这样的设计其实很有灵性。

 

总结

适配器模式经常会出现在一些成熟的框架中,因为成熟的框架一些扩展会使用到它,一开始我们在设计程序的时候其实并不会用到这个模式,因为我们会直接考虑其实现,而不会去为了兼容设计。

 

 

作者:LinkinStar
转载请注明出处
全部案例请看:https://www.cnblogs.com/linkstar/category/1087887.html

 

posted @ 2019-03-08 11:22  LinkinStar  阅读(428)  评论(0编辑  收藏  举报