• 适配器模式-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正在处理");
        }
    }

    二、示例

    在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

  • 相关阅读:
    oh forever love~
    PostgreSQL数据库忘记密码的解决方案
    vue
    无法启动postgresql的错误
    Goaccess解析nginx日志备忘
    pg备份恢复与设置编码
    django+uwsgi+nginx+postgresql备忘
    Git 直接推送到生产服务器
    为了性能, 数据操作尽量在数据库层面进行
    简单理解call_user_func和call_user_func_array两个函数
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/10922014.html
Copyright © 2020-2023  润新知