學習目標:精簡程式邏輯,提升程式碼的可讀性。
內容定位:希望通過對委派模式的學習,讓自己寫出更加優雅的程式碼的人群。
委派模式定義:
- 委派模式(Delegate Pattern)的基本作用是負責任務的排程和分配任務,跟代理模式很像,可以看作是一種特殊情況下的靜態代理的全權代理,但是代理模式注重過程,而委派模式注重結果。
- 不屬於GOF 23中設計模式之一
- 屬於行為型模式
常見應用場景案例:
- DispatcherServlet
- 類名以Delegate結尾的
- 包含Dispatcher的一般都是委派模式
- Spring框架IOC中的BeanDefinitionParserDelegate:Spring提供多種方式(java、xml、註解)配置bean,該類負責分發處理,注入的bean資訊最終會被載入為一個BeanDefition物件(描述物件資訊)
應用場景:解決多工,又不希望把這些任務或者具體的實現讓使用者知道(不讓使用者直接互動),建立一箇中間類,實現全權代理,達到對使用者來說只有一個入口的目的。
簡單程式碼案例
例子:老闆需要安排任務給員工,但是又不能直接讓老闆去了解每個員工的擅長職能,就可以建立一箇中間的經理職位負責瞭解職員的特長,分發任務。
boss類
/** * @ClassName Boss * @Author 周聰 * @Date 2021/1/9 15:48 * @Version 1.0 * @Description 老闆釋出命令 */ public class Boss { /** * 發任務 * @param command * @param leader */ public void command(String command,Leader leader){ leader.doing(command); } }
經理類
/** * @ClassName Leader * @Author 周聰 * @Date 2021/1/9 16:04 * @Version 1.0 * @Description 專案經理 */ public class Leader { // 預先知道每個員工的特長、特徵,分發任務 private Map<String,IEmployee> register = new HashMap<String,IEmployee>(); public Leader(){ register.put("加密",new EmployeeA()); register.put("架構",new EmployeeB()); } public void doing(String command){ // 交給指定的員工去做 register.get(command).doing(command); } }
員工介面
/** * @ClassName IEmployee * @Author 周聰 * @Date 2021/1/9 16:05 * @Version 1.0 * @Description 員工介面 */ public interface IEmployee { /** * 做事 * @param command */ void doing(String command); }
員工A
/** * @ClassName EmployeeA * @Author 周聰 * @Date 2021/1/9 16:07 * @Version 1.0 * @Description 員工A */ public class EmployeeA implements IEmployee { @Override public void doing(String command) { System.out.println("我是員工A,我開始幹活了,我擅長加密,執行"); } }
員工B
/** * @ClassName EmployeeB * @Author 周聰 * @Date 2021/1/9 16:09 * @Version 1.0 * @Description 員工B */ public class EmployeeB implements IEmployee { @Override public void doing(String command) { System.out.println("我是員工B,我擅長架構,我開始幹活了"); } }
測試類
/** * @ClassName DelegateTest * @Author 周聰 * @Date 2021/1/9 16:18 * @Version 1.0 * @Description */ public class DelegateTest { public static void main(String[] args) { new Boss().command("架構",new Leader()); } }
SpringMvc的DispatcherServlet簡單實現
DispatcherServlet是前端控制器委派模式的實現,提供Spring Web MVC的集中訪問點,負責職責的分派
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>delegateServlet</servlet-name> <servlet-class>com.zc.pattern.delegate.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> <!-- http://localhost:8080/getMemberById.do --> </web-app>
DispatcherServlet
package com.zc.pattern.delegate.mvc; import com.zc.pattern.delegate.mvc.controllers.MemberController; import com.zc.pattern.delegate.mvc.controllers.OrderController; import com.zc.pattern.delegate.mvc.controllers.SystemController; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @ClassName DispatcherServlet * @Author 周聰 * @Date 2021/1/9 16:31 * @Version 1.0 * @Description */ public class DispatcherServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 完成排程 doDispach(req,resp); } private void doDispach(HttpServletRequest req, HttpServletResponse resp) throws IOException { String uri = req.getRequestURI(); if ("getMemberById".equals(uri)){ String mid = req.getParameter("mid"); new MemberController().getMemberById(mid); }else if ("getOrderById".equals(uri)){ String oid = req.getParameter("oid"); new OrderController().getOrderById(oid); }else if ("getSystemById".equals(uri)){ new SystemController().logout(); }else { resp.getWriter().write("404 not found"); } } }
MemberController
/** * @ClassName MemberController * @Author 周聰 * @Date 2021/1/9 17:09 * @Version 1.0 * @Description */ public class MemberController { public void getMemberById(String mid){ System.out.println("獲取員工id"); } }
OrderController
/** * @ClassName OrderController * @Author 周聰 * @Date 2021/1/9 17:10 * @Version 1.0 * @Description */ public class OrderController { public void getOrderById(String oid){ System.out.println("獲取訂單id"); } }
SystemController
/** * @ClassName SystemController * @Author 周聰 * @Date 2021/1/9 17:11 * @Version 1.0 * @Description */ public class SystemController { public void logout(){ System.out.println("退出"); } }
以上對單例模式的介紹到此結束,歡迎批評指正。 附:原始碼地址