【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代碼運行之后,結果如下:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM