【菜鳥學院】精通Spring框架——07委派模式

場景

委派模式不屬於GOF23種設計模式,委派模式的基本作用就是負責任務的調用和分配,跟代理模式很像,可以看作一種特殊情況下的靜態全權代理,但是代理模式注重過程,而委派模式注重結果。
委派模式在Spring中的應用非常多,常用的DispatcherServlet就用到了委派模式。
現實生活中也常有委派的場景,例如老闆給項目經理下達任務,經理再給每個員工下達任務,當員工完成任務後,再由項目經理向老闆彙報結果。

員工接口:

public interface IEmployee {
    void doing(String command);
}

創建員工類A和B:

public class EmployeeA implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是員工A,我開始幹"+command+"工作");
    }
}
public class EmployeeB implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是員工B,我開始幹"+command+"工作");
    }
}

創建項目經理類Leader:

public class Leader implements IEmployee {
    
    private Map<String,IEmployee> targets=new HashMap<>();
    
    public Leader(){
        targets.put("加密",new EmployeeA());
        targets.put("登陸",new EmployeeB());
    }
    
    @Override
    public void doing(String command) {
        targets.get(command).doing(command);
    }
}

創建Boss類下達命令:

public class Boss {
    
    public void command(String command,Leader leader){
        leader.doing(command);
    }
}

測試代碼如下:

	public static void main(String[] args) {
        new Boss().command("登陸",new Leader());
    }

代理模式注重的是過程,委派模式注重的是結果
策略模式注重可擴展性,委派模式注重內部的靈活性和可複用性
委派模式的核心就是分發、調度、派遣,委派模式是靜態代理和策略模式的一種特殊組合


委派模式在源碼中的體現

接下來我們還原一下SpringMVC的DispatcherServlet是如何實現委派模式的。
創建業務類MemberController:

public class MemberController {
    public void getMemberById(String mid){
        
    }
}

OrderController類如下:

public class OrderController {
    
    public void getOrderById(String mid){
        
    }
}

SystemController類如下:

public class SystemController {
    
    public void logout(){}
}

創建DispatcherServlet類:

//相當於項目經理的角色
public class DispatcherServlet extends HttpServlet {

    private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
        String uri=request.getRequestURI();
        System.out.println("uri: "+uri);
        String mid=request.getParameter("mid");
        System.out.println("mid: "+mid);


        if("/getMemberById".equals(uri)) {
            System.out.println("通過mid獲取成員");
            new MemberController().getMemberById(mid);
        }
        else if("/getOrderById".equals(uri))
            new OrderController().getOrderById(mid);
        else if("/logout".equals(uri))
            new SystemController().logout();
        else
            response.getWriter().write("404 NOT FOUND!");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) {
        try{
            doDispatch(req, resp);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">


    <servlet>
        <servlet-name>delegateServlet</servlet-name>
        <servlet-class>_06委派模式.MVC.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>delegateServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

測試結果:
在這裏插入圖片描述
在Spring中還有很多用到委派模式的地方,以Delegate結尾的地方都實現了委派模式。例如BeanDefinitionPareserDelegate,根據不同類型委派不同的邏輯解析BeanDefinition。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章