zoukankan      html  css  js  c++  java
  • spring常用模式--委派模式

    1.委派模式简介

    在常用的23种设计模式中其实面没有委派模式(delegate)的影子,但是在Spring中委派模式确实用的比较多的一种模式。

    在spring中的体现:Spring MVC框架中的DispatcherServlet其实就用到了委派模式。

    委派模式的作用: 基本作用就是负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果

    2.委派模式的实例

    先引用一张图来介绍委派模式,下图主要说明了 boss把任务给leader,而leader做了一个任务的分配和调度的工作,自己没有做工作,而是把具体工作交给具体的执行者去做。

    下面直接给出实例:

    执行的接口

    /**
     * @Project: spring
     * @description: 执行的接口
     * @author:
     * @create: 2018-08-30 23:10
     * @ModificationHistory who      when       What
     **/
    public interface IExcuter {
        void excute(String command);
    }

    普通员工A

    /**
     * @Project: spring
     * @description: 员工A执行某项命令
     * @author:
     * @create: 2018-08-30 23:10
     * @ModificationHistory who      when       What
     **/
    public class ExcuterA implements  IExcuter{
    
        @Override
        public void excute(String command) {
            System.out.println("员工A 开始做"+command+"的工作");
        }
    }

    普通员工B

    /**
     * @Project: spring
     * @description: 员工B执行某项命令
     * @author: 
     * @create: 2018-08-30 23:10
     * @ModificationHistory who      when       What
     **/
    public class ExcuterB implements  IExcuter{
        @Override
        public void excute(String command) {
            System.out.println("员工B 开始做"+command+"的工作");
    }
    }

    leader委派者

    /**
     * @Project: spring
     * @description:    leader 委派者   任务分发的作用
     * @author:
     * @create: 2018-08-30 23:11
     * @ModificationHistory who      when       What
     **/
    public class Leader implements  IExcuter {
    
        private Map<String,IExcuter> targets = new HashMap<String,IExcuter>();
        public Leader() {
            targets.put("加密",new ExcuterA());
            targets.put("登录",new ExcuterB());
        }
        @Override
        public void excute(String command) {
            targets.get(command).excute(command);
        }
    }

    boss类模拟调用测试

    /**
     * @Project: spring
     * @description:  boss  模拟客户执行任务
     * @author:
     * @create: 2018-08-30 23:13
     * @ModificationHistory who      when       What
     **/
    public class Boss
    {
        public static void main(String[] args) {
            Leader leader  = new Leader();
            //看上去好像是我们的项目经理在干活
            //但实际干活的人是普通员工
            //这就是典型,干活是我的,功劳是你的
            leader.excute("登录");
            leader.excute("加密");
        }
    }

    测试结果为:

    3.委派模式的实现mvc的简单实例

    思考:
    在springmvc 访问地址的urlController层配置的url是如何映射的
    Controller层配置的url如何跟具体的方法映射的,参数又是如何绑定

    猜测:
    url的地址可以根据request得到访问url地址,配置的url地址可以根据配置注解得到,这两者的url匹配上了说明映射成功了,除了url是不够的,还需要一个中间对象保存了url和method以及controller对象的信息,可以把这个中年的映射对象放入容器中,然后根据传入的url从容器取出进行匹配,取出来之后就可以根据映射来完成方法的调用了。

    下面就简单实现一个mvc调用的例子
    模拟controller层

    /**
     * @Project: spring
     * @description:  模拟controller层
     * @author:
     * @create: 2018-09-03 22:20
     * @ModificationHistory who      when       What
     **/
    public class MemberAction {
    
        public void getMemberById(String mid){
            
        }
    }

    模拟serlvert得到的请求如何转发,交给具体的controller处理的

    /**
     * @Project: spring
     * @description:   selvelt的任务分发者 ,主要完成url的映射和调用
     * @author: sunkang
     * @create: 2018-09-03 22:21
     * @ModificationHistory who      when       What
     **/
    public class SelvletDispatcher {
        //这里也可以用map 对象来保存Hanlder对象
        private List<Handler> handlerMapping = new ArrayList<Handler>();
        
        public SelvletDispatcher() {
            //简单实现一个controller的映射
            try {
          Class clazz  = MemberAction.class;
    
                handlerMapping.add(new Handler()
                                .setController(clazz.newInstance())
                                .setMethod(clazz.getMethod("getMemberById",new Class[]{String.class}))
                                .setUrl("/web/getMemberById.json")
                );
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void  doService(HttpServletRequest request, HttpServletResponse response){
            doDispatch(request,response);
        }
    
        /**
         * 请求的分发工作
         * @param request
         * @param response
         */
        private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
          //1.获取用户请求的url
          String uri =   request.getRequestURI();
          Handler handler =null;
    
          ////2、根据uri 去handlerMapping找到对应的hanler
          for(Handler h :handlerMapping){
              if(uri.equals(h.getUrl())){
                  handler = h;
                  break;
              }
          }
          //3.将具体的任务分发给Method(通过反射去调用其对应的方法)
            Object obj = null;
            try {
                obj =  handler.getMethod().invoke(handler.getController(),request.getParameter("mid"));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            //4、获取到Method执行的结果,通过Response返回出去
            // response.getWriter().write();
    
        }
        /**
         * 具体的hanlder对象
         */
        class Handler{
            //controller对象
            private Object controller;
            //controller对象映射的方法
            private  String url;
            //ulr对应的方法
            private Method method;
    
            public Object getController() {
                return controller;
            }
    
            public Handler setController(Object controller) {
                this.controller = controller;
                return this;
            }
    
            public String getUrl() {
                return url;
            }
    
            public Handler setUrl(String url) {
                this.url = url;
                return  this;
            }
    
            public Method getMethod() {
                return method;
            }
    
            public Handler setMethod(Method method) {
                this.method = method;
                return this;
            }
        }
    }
  • 相关阅读:
    轻松记账方法(A)
    个人学习进度(第八周)
    个人学习进度(第八周)
    Web版四则运算
    个人学习进度(第七周)
    个人学习进度(第六周)
    数组的子数组和最大值
    个人学习进度(第五周)
    个人学习进度(第四周)
    个人学习进度(第三周)
  • 原文地址:https://www.cnblogs.com/pypua/p/11375631.html
Copyright © 2011-2022 走看看