适配器模式-Adapter

适配器模式是将一个类的接口转换成客户希望的另一个接口,从而让那些接口不兼容的类可以一起工作。

一、类图结构

适配器模式包含以下三个角色:

  • Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。在类适配器中,由于C#语言不支持多重继承,所以它只能是接口。
  • Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。
  • Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

将上面的类图可以转换如下的代码

public class AdapterClient {

    private List<Adaptor> adaptors = new ArrayList<Adaptor>();

    public AdapterClient(){
        adaptors.add(new Target1Adaptor());
        adaptors.add(new Target2Adaptor());
    }

    /**
     * 获取目标对象对应的适配器
     */
    public Adaptor getAdaptor(Target target) {
        for (Adaptor adaptor : this.adaptors) {
            if (adaptor.supports(target)) {
                return adaptor;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        AdapterClient client = new AdapterClient();
        //目标
        Target target = new Target1();
        //Target target = new Target2();

        //获取目标对应的适配器
        Adaptor adaptor = client.getAdaptor(target);

        //处理
        adaptor.specificRequest(target);
    }

}

/**
 * 适配器接口
 */
interface Adaptor {
    /**
     * 当前适配器是否支持该目标
     */
    boolean supports(Target target);

    /**
     * 调用支持的目标对象的处理方法。仅当support()返回true时调用
     */
    void specificRequest(Target target);
}

/**
 * 目标1适配器
 */
class Target1Adaptor implements Adaptor {

    @Override
    public boolean supports(Target target){
        //仅支持Target1
        return (target instanceof Target1);
    }

    @Override
    public void specificRequest(Target target) {
        ((Target1)target).request();
    }
}

/**
 * 目标2适配器
 */
class Target2Adaptor implements Adaptor {

    @Override
    public boolean supports(Target target) {
        //仅支持Target2
        return (target instanceof Target2);
    }

    @Override
    public void specificRequest(Target target) {
        ((Target2)target).request();
    }
}

/**
 * 被适配的目标接口:Adaptee
 */
interface Target {
    void request();
}

/**
 * 具体的目标1
 */
class Target1 implements Target{

    @Override
    public void request() {
        System.out.println("Target1正在处理");
    }
}

/**
 * 具体的目标2
 */
class Target2 implements Target {

    @Override
    public void request() {
        System.out.println("Target2正在处理");
    }
}

二、Spring中的适配器模式

在SpringMVC中,DispatcherServlet类中的doDispatch方法在查找Controller时,就用到了适配器模式,可以参考DispatcherServlet的工作原理

我们可以用下面的不同方式来声明Controller

interface Controller {
    void handleRequest();
}

class HttpRequestHandler implements Controller {
    @Override
    public void handleRequest() {
        System.out.println("HttpRequestHandler正在处理请求");
    }
}

class RequestMappingHandler implements Controller {
    @Override
    public void handleRequest() {
        System.out.println("RequestMappingHandler正在处理请求");
    }
}

class SimpleHandler implements Controller {
    @Override
    public void handleRequest() {
        System.out.println("SimpleHandler正在处理请求");
    }
}

HandlerAdaptor

interface HandlerAdaptor {

    boolean supports(Object handler);

    void handle(Object handler);
}

class HttpRequestHandlerAdapter implements HandlerAdaptor{
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof HttpRequestHandler);
    }

    @Override
    public void handle(Object handler) {
        ((HttpRequestHandler)handler).handleRequest();
    }
}

class RequestMappingHandlerAdapter implements HandlerAdaptor {
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof RequestMappingHandler);
    }

    @Override
    public void handle(Object handler) {
        ((RequestMappingHandler)handler).handleRequest();
    }
}

class SimpleHandlerAdapter implements HandlerAdaptor {
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof SimpleHandler);
    }

    @Override
    public void handle(Object handler) {
        ((SimpleHandler) handler).handleRequest();
    }
}

DispatcherServlet

public class DispatcherServlet {

    private List<HandlerAdaptor> handlerAdaptors = new ArrayList<HandlerAdaptor>();

    public DispatcherServlet() {
        handlerAdaptors.add(new RequestMappingHandlerAdapter());
        handlerAdaptors.add(new HttpRequestHandlerAdapter());
        handlerAdaptors.add(new SimpleHandlerAdapter());
    }

    public HandlerAdaptor getHandler(Controller controller) {
        for (HandlerAdaptor adapter : this.handlerAdaptors) {
            if (adapter.supports(controller)) {
                return adapter;
            }
        }
        return null;
    }

    /**
     * 请求分发
     */
    public void doDispatch() {
        // 模拟SpringMVC从request取handler的对象。
        //HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

        //Controller controller = new HttpRequestHandler();
        //Controller controller = new RequestMappingHandler();
        Controller controller = new SimpleHandler();
        // 不论何种类型Controller,总是通过获取对应的适配器。
        HandlerAdaptor ha = getHandler(controller);
        // Controller处理请求
        ha.handle(controller);
    }

    public static void main(String[] args) {
        // 实例化DisPatcherServlet
        DispatcherServlet dispatch = new DispatcherServlet();
        // 请求处理分发
        dispatch.doDispatch();
    }
}

由于Controller的类型不同,有多种实现方式,而且调用方式是不确定,如果直接调用Controller方法,则代码中就会出现较多的if-else。因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了,这就是适配器模式的精妙之处!

 

 ……更多设计模式的内容,可以访问Refactoring.Guru

 

posted @ 2018-08-27 22:13  静水楼台/Java部落阁  阅读(326)  评论(0编辑  收藏  举报