定义:将一个类的接口转换成客户端希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作
举例:苹果安卓接口转换器,电源适配器:220V交流转换直流,手语老师,jdbc-odbc bridge
1:类适配器模式
适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比较高,使用比较少
2:对象适配器模式
3:接口适配器模式(也不算适配器)
类适配器
类适配器模式违背了合成复用原则,类适配器是客户类(target)有一个接口规范的情况下可用,反之不可用
合成复用原则:尽量先使用组合和聚合的关系来实现,其次才考虑使用继承关系来实现
对象适配器
接口适配器:
java.awt.event.WindowAdapter
应用场景:
新老版本接口兼容问题,以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致
使用第三方提供的组件,单组件接口定义和自己要求的接口定义不同
常见的适配器使用场景:
1:Spring MVC的适配器模式
在Spring-framwork中提供了spring mvc 的开发包,我们在用spring mvc中,它实现控制器的方式有很多中。例如我们常用@Controller注解,还有实现Controller接口或者实现HttpRequestHandler接口等等。而在DispatcherServlet中如何处理这三种不同的控制器呢,它用到了适配器,用于对不同的实现方式适配
springmvc源码分析
1.1: HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
1.2:HandlerAdatepter接口有如下子处理请求适配器 public class HandlerFunctionAdapter implements HandlerAdapter
public boolean supports(Object handler) {
return handler instanceof HandlerFunction;
} public class HttpRequestHandlerAdapter implements HandlerAdapter
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
public class RequestMappingHandlerAdapter extends
AbstractHandlerMethodAdapter 注解方式
public final boolean supports(Object handler) {
return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
} public class SimpleControllerHandlerAdapter implements HandlerAdapter public class SimpleServletHandlerAdapter implements
HandlerAdapter
1.3 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
2:JDK的Read(字符流)、InputStream(字节流 ) ,InputStreamReader两者的适配器
InputStream方法实现:
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
public int read() throws IOException {
return sd.read();
}
}
// 场景2:jdk
FileInputStream fis = new FileInputStream("c:/test.txt");
// 适配器,将inputstream转成reader
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while (line != null && !line.equals("")) {
System.out.println(line);
}
br.close();
类图:
从上图可以看出:
InputSreamReader是对同样实现了Reader的StreamDecorder的封装
StreamDecoder不是java SE API中的内容,是Sun JDK给出的自身实现。但我们知道他们对构造方法中的字节流类(InpuStream)进行了封装,并通过该类进行了字节流和字符流之间的解码转换
结论:
从表层看,InputStreamReader做了InpuStream字节流到Reader字符流之间的转换,而从如上Sun JDK的实现类关系结构可以看出,是StreamDecoder的设计实现在实际上采用了适配器模式
3:Mybatis多种日志框架适配器模式源码分析
适配器快速入门例子:
比如早期的时候V1版本订单接口的入参为Map类型,随着业务的更新和迭代在V2版本的时候该订单接口的入参需要支持List类型?请问:在不改变原有接口代码的情况下,如何实现支持List类型?