适配器模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
- 什么是适配器模式
- 有几种适配器种类(了解)
- 应用场景
- 应用场景简单实现
什么是适配器模式
如图,将4个口最终转为一个口的能力,实现了很好的兼容
在程序对应中,将多个对象类型转为一个对象类型去调用方法
有几种适配器种类(了解)
类适配器
适配器类需要继承被适配器类(原来的东西)实现目标接口(转换得到的东西)
缺点:继承耦合性强,暴露了被适配器中的方法,好处是可以重写
对象适配器
不在继承,而是new一个实例,系统中尽量不使用继承关系,所以对象适配器是常用的一种
接口适配器
有些适配方法不需要全部实现,这种情况下可以使用一个抽象类实现接口中的全部方法,然后用匿名内部类的方式实现自己用的方法。类似于监听器类
应用场景
springmvc中的DispatcherServlet类中doDispatch方法中很清楚的出现了适配器的影子,只要把这块为什么作者使用适配器搞懂了,这个模式也就理解大半了,剩下的就是不断实践
1、首先根据传入的request来获取对应的handler
2、利用获取的handler获取适配器类adapter
3、利用该适配器调用对应的方法
为什么用适配器,直接根据handler调对应方法不就可以了?
①不知道获得的handler类型,需要判断,这本身也是一个适配的过程
常用的handler有:Controller,HttpRequestHandler、Servlet。而它们都属于不同的类型,调用的方法名也不同
②这里的handler被封装为了HandlerExecutionChain对象
这个类不知道获取的handler是什么类型,接口中虽然有获取handler方法,但返回类型为object。这时候需要用到handlerMapping来找对应的handler
③那为什么不用handlerMapping来调用方法?
基于单一职责,一个类只做一件事情, 这个类的作用就是处理请求与handler的对应关系,调用是有各自的handler去提供
④每个handler实现方式不同,但有个共同特点,传参都有request与response,那么就可以设置一个适配器类,传入相同的参数在给一个handler类型,来帮不同的handler提供一个统一的调用方法,起到适配的作用,可以联想以下扩展坞,假如你的电脑只支持c口,那么想用a口,hdmi口,就需要扩展坞,扩展坞的好处是方便,不管有什么口最终都可以转为一个口,而且好扩展
适配器类的好处
只需要给我一个handler类型的对象就可以,具体是什么不用管。
如果进行扩展,只需要添加适配器类就可以,调用方无需修改
不用适配器,能不能实现?
可以,首先同样得到handler,然后遍历if-else判断得到具体的handelr类型,在调各自的方法即可,但不方便扩展,每次都需要改调用方代码,违反开闭原则。所以适配器也可以看作高级版的if-else
适配器类在源码中是怎么实现的?
举个例子,如果为HttpRequestHandler类型,则强转为这个类型,然后调用
简单的MVC实现
uml类图
先画出类图,再根据类图实现代码
定义handler接口,实现该接口标识为handler
1 | public interface Handler {} |
HttpHandel
1 | class HttpHandel implements Handler { |
SimpleHandel
1 | class SimpleHandel implements Handler { |
定义adapter接口
1 | public interface HandlerAdapter { |
实现该接口
1 | class HttpHandlerAdapter implements HandlerAdapter { |
模拟DispaterServlet类
1 | public class DispatcherServletTest { |