委派模式(Delegate Pattern)的基本做用就是負責任務的調度和分配任務,跟代理模式很像,能夠看作是一種特殊狀況下的靜態代理的全權代理,可是代理模式注重過程,而委派模式注重結果。java
1 不屬於GOF 23種設計模式之一。web
2 屬於行爲型模式json
3 Delegate 結尾的通常都是委派,Dispatcher設計模式
委派模式在 Spring 中應用很是多,經常使用的 DispatcherServlet 其實就是用到了委派模式瀏覽器
在 Spring 源碼中,只要以 Delegate 結尾的都是實現了委派模式。例如:BeanDefinitionParserDelegate 根據不一樣類型委派不一樣的app
public interface IEmployee { void doing(String command); }
public class EmployeeB implements IEmployee { @Override public void doing(String command) { System.out.println("我是員工B,我如今開始幹" + command + "工做"); } }
public class EmployeeA implements IEmployee { @Override public void doing(String command) { System.out.println("我是員工A,我如今開始幹" + command + "工做"); } }
public class Leader implements IEmployee { private Map<String,IEmployee> targets = new HashMap<String,IEmployee>(); public Leader() { targets.put("加密",new EmployeeA()); targets.put("登陸",new EmployeeB()); } //項目經理本身不幹活 public void doing(String command){ targets.get(command).doing(command); } }
public class Boss { public void command(String command,Leader leader){ leader.doing(command); } }
public static void main(String[] args) { //客戶請求(Boss)、委派者(Leader)、被被委派者(Target) //委派者要持有被委派者的引用 //代理模式注重的是過程, 委派模式注重的是結果 //策略模式注重是可擴展(外部擴展),委派模式注重內部的靈活和複用 //委派的核心:就是分發、調度、派遣 //委派模式:就是靜態代理和策略模式一種特殊的組合 new Boss().command("加密", new Leader()); }
SpringMVC:ide
public class MemberController { public void getMemberById(String mid){ } }
public class OrderController { public void getOrderById(String mid){ } }
public class SystemController { public void logout(){ } }
public class DispatcherServlet extends HttpServlet{ private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{ String uri = request.getRequestURI(); String mid = request.getParameter("mid"); if("getMemberById".equals(uri)){ 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!!"); } } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doDispatch(req,resp); } catch (Exception e) { e.printStackTrace(); } } }
邏輯解析 BeanDefinition this
策略模式:加密
private List<Handler> handlerMapping = new ArrayList<Handler>(); public void init() throws ServletException { try { Class<?> memberControllerClass = MemberController.class; handlerMapping.add(new Handler() .setController(memberControllerClass.newInstance()) .setMethod(memberControllerClass.getMethod("getMemberById", new Class[]{String.class})) .setUrl("/web/getMemberById.json")); }catch(Exception e){ } } private void doDispatch(HttpServletRequest request, HttpServletResponse response){ //一、獲取用戶請求的url // 若是按照J2EE的標準、每一個url對對應一個Serlvet,url由瀏覽器輸入 String uri = request.getRequestURI(); //二、Servlet拿到url之後,要作權衡(要作判斷,要作選擇) // 根據用戶請求的URL,去找到這個url對應的某一個java類的方法 //三、經過拿到的URL去handlerMapping(咱們把它認爲是策略常量) Handler handle = null; for (Handler h: handlerMapping) { if(uri.equals(h.getUrl())){ handle = h; break; } } //四、將具體的任務分發給Method(經過反射去調用其對應的方法) Object object = null; try { object = handle.getMethod().invoke(handle.getController(),request.getParameter("mid")); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //五、獲取到Method執行的結果,經過Response返回出去 try { response.getWriter().write(object.toString()); } catch (IOException e) { e.printStackTrace(); } } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doDispatch(req,resp); } catch (Exception e) { e.printStackTrace(); } } class Handler{ private Object controller; private Method method; private String url; public Object getController() { return controller; } public Handler setController(Object controller) { this.controller = controller; return this; } public Method getMethod() { return method; } public Handler setMethod(Method method) { this.method = method; return this; } public String getUrl() { return url; } public Handler setUrl(String url) { this.url = url; return this; } }