结构性:从程序的结构上实现松耦会,从而可以扩大整体的类结构,用来解决更大的问题。
模式都来源于生活,举一个生活的列子
//要被适配的类 网线
public class Adatee {
public void request(){
System.out.println("连接网线上网");
}
}
//接口转换器的抽象实现
public interface NettoUsb {
//作用:处理请求 能网的接口
public void handleRequest();
}
//类适配器 继承
public class Adapter extends Adatee implements NettoUsb{
@Override
public void handleRequest() {
super.request();//可以上网了
}
}
//对象适配器
public class Adapter2 implements NettoUsb{
private Adatee adatee;
public Adapter2(Adatee adatee) {
this.adatee = adatee;
}
@Override
public void handleRequest() {
adatee.request();//可以上网了
}
}
//客户端类 电脑想上网 插不上网线
public class Computer {
public void net(NettoUsb nettoUsb){
//上网的具体实例 找一个转接头
nettoUsb.handleRequest();
}
public static void main(String[] args) {
//电脑 网线 适配器
//类适配器
Computer computer = new Computer();
Adapter adapter = new Adapter();
computer.net(adapter);
//对象适配器
Computer computer1 = new Computer();
Adatee adatee1 = new Adatee();
Adapter2 adapter1 = new Adapter2(adatee1);
computer1.net(adapter1);
}
}
对象适配器优点
一个对象适配器可以把多个不同的适配者适配到同一个目标
可以适配一个适配者的子类,由于适配器和适配者之间是关联关系,根据“里氏代换原则”,适配者
的子类也可通过该适配器进行适配。
类泛配器缺点
对于Java支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配
适用场景
想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
例如:springmvc中
用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet,DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller,HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet,
Spring MVC中的Controller种类众多,不同类型的Controller通过不同的方法来对请求进行处理。如果不利用适配器模式的话,DispatcherServlet直接获取对应类型的Controller,需要的自行来判断,实现该接口的适配器每一个Controller都有一个适配器与之对应,这样的话,每自定义一个Controller需要定义一个实现HandlerAdapter处理器适配器。
if(mappedHandler.getHandler() instanceof MultiActionController){
((MultiActionController)mappedHandler.getHandler()).xxx
}else if(mappedHandler.getHandler() instanceof XXX){
...
}else if(...){
...
}
这样假设如果我们增加一个HardController,就要在代码中加入一行 if(mappedHandler.getHandler() instanceof HardController)
这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 – 对扩展开放,对修改关闭。 因此也就引入了适配器模式,来看看它是怎么运用的:
首先定义一个适配器接口:
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception;
}
public class HttpRequestHandlerAdapter implements HandlerAdapter {
public HttpRequestHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
((HttpRequestHandler)handler).handleRequest(request, response);
return null;
}
public long getLastModified(HttpServletRequest request, Object handler) {
return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
}
}
当Spring容器启动后,会将所有定义好的适配器对象存放在一个List集合中,当一个请求来临时,DispatcherServlet会通过handler的类型找到对应适配器,并将该适配器对象返回给用户,然后就可以统一通过适配器的hanle()方法来调用Controller中的用于处理请求的方法。