乐趣区

设计模式学习笔记适配器模式

一、结构型设计模式

1、概念
结构型设计模式描述 如何将类或者对象结合在一起形成更为复杂,功能更为强大的结构。

2、分类
(1) 类结构模型 :这种结构模型关心类的组合,类直接组合成一个更大的系统,通常用继承来建立这种关系。
(2) 对象结构模型:这种模型结构关心类与对象的组合,通常在一个类中使用另一个类的对象,再调用其方法。

注:“合成复用原则”规定尽量用关联关系来代替继承关系,因此一般使用对象结构模型。

二、适配器模式

1、概念
适配器模式是一种结构型模式,它的思想是 将一个接口转化为另一个接口。
适配器模式包含四个角色:
(1)对象:定义所需要的方法
(2)请求者:负责使用对象定义的方法来做具体的处理
(3)被适配者:以持有方法的角色
(4)适配器:使用被适配者的方法来满足对象的需要。

2、代码示例 :使用安卓充电器给苹果充电
(1) 安卓和苹果充电器接口

// 安卓
public interface MicroUsbInterface {public void chargeWithMicroUsb();
}

// 苹果
public interface LightningInterface {public void chargeWithLightning();
}

(2)安卓设备充电器

public class AndroidCharger implements MicroUsbInterface {
    @Override
    public void chargeWithMicroUsb() {System.out.println("使用 MicroUsb 型号的充电器充电...");
    }
}

(3)适配器(用安卓充电器适配苹果充电器)

public class Adapter implements LightningInterface {
    // 将安卓充电器的接口作为一个字段
    private MicroUsbInterface microUsbInterface;

    public Adapter() {}

    public Adapter(MicroUsbInterface microUsbInterface) {this.microUsbInterface = microUsbInterface;}

    @Override
    public void chargeWithLightning() {
        // 使用安卓充电器给苹果设备充电
        microUsbInterface.chargeWithMicroUsb();}

    public MicroUsbInterface getMicroUsbInterface() {return microUsbInterface;}

    public void setMicroUsbInterface(MicroUsbInterface microUsbInterface) {this.microUsbInterface = microUsbInterface;}
}

在这个示例中,对象就是给苹果手机充电,请求者就是苹果手机,被适配者是安卓充电器,适配器是用安卓充电器给苹果手机充电的适配器。

3、适用场景
(1) 系统想要使用现有类,但这个类的接口不符合系统需要

(2)想要建立一个可以重复使用的类,用在一些没有关联的类之间

(3)通过接口转换将一个类插到另一个类系当中。(比如新增一个飞狗类,就可以实现飞的接口,并且增加一个狗字段)

4、优缺点
(1) 优点:将目标和被适配者解耦,通过适配器来关联,同时具有 透明性、复用性、灵活性和扩展性

(2)缺点:过度的使用适配器会让系统显得比较凌乱。

三、适配器应用

1、SpringMVC 的 HandleAdapter 使用了适配器模式的思想

SpringMVC 中的 handler(Controller,HttpRequestHandler,Servlet)的实现方式是多重的,可以是继承 controller 的,也可能是注解控制器方式的。
因此如果是正常的调用,需要通过 if else 语句去判断,这样就会破坏开闭原则。

为了解决这个问题,Spring 定义了一个适配接口,使得每一个 handler 都有一种对应的适配器实现类,让适配器代替 handler 执行相应的方法。这样在扩展 Controller 时,只需要增加一个适配器类就完成了 SpringMVC 的扩展了。

// 定义一个 Adapter 接口  
public interface HandlerAdapter {public boolean supports(Object handler);  
    public void handle(Object handler);  
}  
这是一段模拟的代码
// 以下是三种 Controller 实现  
public interface Controller { }  
//HTTP 请求处理器
public class HttpController implements Controller{public void doHttpHandler(){System.out.println("http...");  
    }  
}  
// 继承 Controller 方式
public class SimpleController implements Controller{public void doSimplerHandler(){System.out.println("simple...");  
    }  
}  

// 注解方式
public class AnnotationController implements Controller{public void doAnnotationHandler(){System.out.println("annotation...");  
    }  
}  


// 下面编写适配器类  

public class SimpleHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((SimpleController)handler).doSimplerHandler();}  

    public boolean supports(Object handler) {return (handler instanceof SimpleController);  
    }  

}  


public class HttpHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((HttpController)handler).doHttpHandler();}  

    public boolean supports(Object handler) {return (handler instanceof HttpController);  
    }  

}  

public class AnnotationHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((AnnotationController)handler).doAnnotationHandler();}  

    public boolean supports(Object handler) {return (handler instanceof AnnotationController);  
    }  

}  


// 模拟一个 DispatcherServlet  
import java.util.ArrayList;  
import java.util.List;  

public class DispatchServlet {public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();   

    public DispatchServlet(){handlerAdapters.add(new AnnotationHandlerAdapter());  
        handlerAdapters.add(new HttpHandlerAdapter());  
        handlerAdapters.add(new SimpleHandlerAdapter());  
    }  


    public void doDispatch(){  

       // 此处模拟 SpringMVC 从 request 取 handler 的对象,仅仅 new 出,可以出,// 不论实现何种 Controller,适配器总能经过适配以后得到想要的结果  
       //HttpController controller = new HttpController();  
       //AnnotationController controller = new AnnotationController();  
        SimpleController controller = new SimpleController();  
        // 得到对应适配器  
        HandlerAdapter adapter = getHandler(controller);  
        // 通过适配器执行对应的 controller 对应方法  
        adapter.handle(controller);  
    }  

// 遍历注入的 handleradapter 找到合适的适配器子类
    public HandlerAdapter getHandler(Controller controller){for(HandlerAdapter adapter: this.handlerAdapters){if(adapter.supports(controller)){return adapter;}  
        }  
        return null;  
    }  

    public static void main(String[] args){new DispatchServlet().doDispatch();}  

}  
 

参考:看 springmvc 适配器模式 —HandlerAdapter https://blog.csdn.net/a362212…
设计模式(十一)——适配器模式
https://www.hollischuang.com/…
《图解设计模式》

退出移动版