zoukankan      html  css  js  c++  java
  • 【Spring源码解析】—— 委派模式的理解和使用

    一、什么是委派模式

    委派模式,是指什么呢?从字面含义理解,委派就是委托安排的意思,委派模式就是在做具体某件事情的过程中,交给其他人来做,这个事件就是在我的完整链路上的一部分,但是复杂度较高的情况下或者我不想做的情况下,完全可以委派给另一个类来处理,只要这个结果是符合我的预期的就可以(相当于填空)。

    模板模式与委派模式的区别:模板模式更关注步骤,公共部分会放在模板的骨架步骤中完成,针对子类可能会有特殊的一些操作就可以在特定步骤中重新实现,从模板模式中能够看到清晰的过程步骤。

    代理模式与委派模式的区别:代理模式就是这个事情就根本不是我做的,但是我只能提供其中关键的一些信息,其他的周边或者在此基础上的扩展都可以交给其他人来做,完整的一个问题,能够得到解决(这是目前理解到的代理模式,后续如果有更新,会重新对这里进行修改)

    二、Spring中的应用

    (一)   iOC相关部分中,在进行对象实例化的过程有用到委派模式?

    在doRegisterBeanDefinitions()即BeanDefinition进行注册的过程中,会设置BeanDefinitionParserDelegate类型的Delegate对象传给this.delegate,并将这个对象作为一个参数传给:parseBeanDefinitions(root, this.delegate)中,然后主要的解析的工作就是通过delegate作为主要角色来完成的,可以看到下方代码:

    /**
    
     * Parse the elements at the root level in the document:
    
     * "import", "alias", "bean".
    
     * @param root the DOM root element of the document
    
     */
    
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    
       //判断节点是否属于同一命名空间,是则执行后续的解析
    
       if (delegate.isDefaultNamespace(root)) {
    
          NodeList nl = root.getChildNodes();
    
          for (int i = 0; i < nl.getLength(); i++) {
    
             Node node = nl.item(i);
    
             if (node instanceof Element) {
    
                Element ele = (Element) node;
    
                if (delegate.isDefaultNamespace(ele)) {
    
                   parseDefaultElement(ele, delegate);
    
                }
    
                else {
    
                   //注解定义的Context的nameSpace进入到这个分支中
    
                   delegate.parseCustomElement(ele);
    
                }
    
             }
    
          }
    
       }
    
       else {
    
          delegate.parseCustomElement(root);
    
       }
    
    }

    其中最终能够走到bean注册部分的是,会进入到parseDefaultElement(ele, delegate)中,然后针对不同的节点类型,针对bean的节点进行真正的注册操作,而在这个过程中,delegate会对element进行parseBeanDefinitionElement,得到了一个BeanDefinitionHolder类型的对象,之后通过这个对象完成真正的注册到Factory的操作

    (二)   在SpringMVC中,类DispatcherServlet,就是:用于HTTP请求处理程序/控制器的中央调度程序,针对通过WEB UI输入的url请求,委派给DispatcherServlet处理,从委派者的角度来看,关注结果即可

    (三)   实际生活的例子:委派可以理解成Leader来做工作,也会做一部分,只是将其中一个部分交给Member来做,Member按照自己的方式做完之后,Leader只关注结果(这是一个两方的关系,代理模式是一个三方的关系,例如房东+中介+租客,中介相对于房东和租客来说,都是代理)。

    三、自写demo示例

    分别为:Leader类、Member类、StaffdoTask类、StaffInfo类、Task类

    其中Task类为:任务类;StaffInfo类:雇员信息类;StaffdoTask类:雇员做任务类;Leader类:组长类(委派者),Member类:组员类(被委派者)

    Task类代码如下:

    public class Task {
        String id;
        String name;
        String step;
        String deadline;
    
        public Task(String id, String name, String step, String deadline) {
            this.id = id;
            this.name = name;
            this.step = step;
            this.deadline = deadline;
        }
    
        public String getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public String getDeadline() {
            return deadline;
        }
    
        public String getStep() {
            return step;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setDeadline(String deadline) {
            this.deadline = deadline;
        }
    
        public void setStep(String step) {
            this.step = step;
        }
    }

    StaffInfo类:

    public class StaffInfo {
        String staffid;
        String staffname;
    
        public StaffInfo(String staffid, String staffname) {
            this.staffid = staffid;
            this.staffname = staffname;
        }
    
        public String getStaffid() {
            return staffid;
        }
    
        public void setStaffid(String staffid) {
            this.staffid = staffid;
        }
    
        public String getStaffname() {
            return staffname;
        }
    
        public void setStaffname(String staffname) {
            this.staffname = staffname;
        }
    }

     StaffdoTask接口,Leader类和Member类实现了该接口

    public interface StaffdoTask {
        public void doTask(StaffInfo staffInfo, Task task);
    }

    Leader类:

    public class Leader{
    
        //假设Leader的角色为区域销售主管,针对店铺进行人员盘点,将A人员分配到1区,将B人员分配到2区
        //店长需要针对区域进行整体管理,包含人员的考勤、日常管理和工作访谈、人员培养等
        //其中销售的工作给到不同的区的人员主负责
    
        public void doTask() {
            Task task_gongzuofangtan = new Task("1", "工作访谈",
                    "1、跟进每个区的工作负责人,2、进行访谈交流,3、汇总结果", "20190823");
            Task task_kaoqin = new Task("2", "考勤管理", "1、查看每日每人的考勤情况,2、输出考勤报表",
                    "20190823");
            Task[] task_xiaoshou = new Task[3];
            Task xiaoshou_1 = new Task("3", "销售", "1、A区域内的人员出售车辆", "2019-0824");
            Task xiaoshou_2 = new Task("3", "销售", "1、B区域内的人员出售车辆", "2019-0824");
            Task xiaoshou_3 = new Task("3", "销售", "1、C区域内的人员出售车辆", "2019-0824");
            task_xiaoshou[0] = xiaoshou_1;
            task_xiaoshou[1] = xiaoshou_2;
            task_xiaoshou[2] = xiaoshou_3;
    
            Task task_huizong = new Task("4", "汇总", "1、将各个区的工作进行整理,2、汇总输出报告", "20190826");
    
            //做自己的工作
            doRealTask(task_gongzuofangtan);
            doRealTask(task_kaoqin);
    
            StaffInfo[] staff_xiaoshou = new StaffInfo[3];
            StaffInfo staff_1 = new StaffInfo("1023", "A");
            StaffInfo staff_2 = new StaffInfo("1024", "B");
            StaffInfo staff_3 = new StaffInfo("1025", "C");
            staff_xiaoshou[0] = staff_1;
            staff_xiaoshou[1] = staff_2;
            staff_xiaoshou[2] = staff_3;
    
            doDispatcherTask(task_xiaoshou, staff_xiaoshou);
    
            doRealTask(task_huizong);
        }
    
        public void doRealTask(Task task){
    //        System.out.println("task info");
            System.out.println("taskid:" + task.id + " taskname:" + task.name +
                    " taskstep:" + task.step + " taskdeadline:" + task.deadline);
        }
    
        //Desc:进行任务分发处理
        public void doDispatcherTask(Task[] tasks, StaffInfo[] staffInfos){
            System.out.println("做销售任务的委派");
            for (int i = 0; i < tasks.length; i++){
                Member member = new Member();
                member.doTask(staffInfos[i], tasks[i]);
            }
        }
    
        public static void  main(String[] args){
            System.out.println("开始工作,并做好任务分派");
            Leader leader = new Leader();
            leader.doTask();
        }
    }

    Member类:

    public class Member implements StaffdoTask{
    
        @Override
        public void doTask(StaffInfo staffInfo, Task task) {
            System.out.println("statff " + staffInfo.staffid + "do the task:" + task.id + " " +task.name
             + " " + task.step + " " + task.deadline);
        }
    }

    其中Leader类的main代码运行之后,结果如下:

     

  • 相关阅读:
    $dp$模板
    字符串基础
    基础算法

    图论
    山中无甲子,寒尽不知年
    模板集合(持续更新)
    数学基础——同余
    9.19 考试总结
    1-5-17:菲波那契数列
  • 原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/11288909.html
Copyright © 2011-2022 走看看