1. 程式人生 > >設計模式之委派模式(不屬於23種經典設計模式之一)

設計模式之委派模式(不屬於23種經典設計模式之一)

介紹

標準定義:委派模式的原理為類B和類A是兩個互相沒有任何關係的類,B具有和A一模一樣的方法和屬性,並且呼叫B中的方法、屬性就是呼叫A中同名的方法和屬性。B好像就是一個受A授權委託的中介。第三方的程式碼不需要知道A的存在,也不需要和A發生直接的聯絡,通過B就可以直接使用A的功能,這樣既能夠使用到A的各種功能,又能夠很好的將A保護起來,一舉兩得。
通俗理解:我們在專案開發中都是一個專案團隊,老闆把任務交給專案經理後,專案經理制定專案計劃、將任務下發到底下的開發人員,這就是委派模式。但是我們發現這個跟之前學的代理模式非常相似,其實這也可以當做是靜態代理模式的一種特例。此外,專案經理接到任務後會做一個權衡,怎麼去選擇分配這些任務。我們又發現這個跟之前學的策略模式非常相似,其實這也可以當做是策略模式的一種特例。(其實設計模式一般都不會獨立存在,都是混合使用)
委派模式跟靜態代理模式以及策略模式的區別?


委派模式:代理人全權負責這一件事。如:老闆給專案經理安排任務,專案經理只是負責排程工作,真正幹活的是底下的開發人員。
靜態代理模式:代理人只是參與被代理人一小部分的工作,最終的結論還是得由代理人來決定。如:張三沒空找物件,媒婆幫張三物色到一個物件,最終得看張三喜不喜歡這個物件。
策略模式:專案經理在分配任務的時候需要權衡,會產生多種分配方案,但是最終都是將手中的任務分配給底下的開發人員。

案例

場景: springmvc框架中的DispatcherServlet其實就是一個典型的委派模式。
程式碼:
1>假設有以下三個action,每個action執行不同的業務操作。

public class MemberAction {
    public void getMemberById(String mid){

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

    } 
}
public class SystemAction {
    public void logout(String mid){

    }
}

2>真實的分發類

//這個類對客戶端發來的請求做分發(類似專案經理分配任務)
public class ServletDispatcher {
    private
List<Handler> handlerMapping=new ArrayList<Handler>(); public ServletDispatcher(List<Handler> handlerMapping) { try{ Class<?> memberActionClass=MemberAction.class; handlerMapping.add(new Handler() .setController(memberActionClass.newInstance()) .setMethod(memberActionClass.getMethod("getMemberById",new Class[]{String.class})) .setUrl("/web/getMemberById.json")); }catch (Exception e){ e.printStackTrace(); } } public void doService(HttpServletRequest request, HttpServletResponse response){ doDispatch(request,response); } private void doDispatch(HttpServletRequest request, HttpServletResponse response){ //1.獲取使用者請求的url //如果按照j2ee標準,每個url會對應一個servlet,url由瀏覽器輸入 //而現在使用委派模式,就只需要配一個url,其他的都交給該類統一管理 String uri=request.getRequestURI(); //2.servlet拿到url以後要做權衡(要做判斷、要做選擇) //根據使用者請求的url,去找到這個url對應的某一個java類的方法 //3.通過拿到的url去handlerMapping中找(我們把它認為是策略常量) Handler handler=null; for(Handler h:handlerMapping){ if(uri.equals(h.getUrl())){ handler=h; break; } } //4.將具體的任務分發給method(通過反射去呼叫其對應的方法) Object object=null; try { object=handler.getMethod().invoke(handler.getController(),request.getParameter("mid")); }catch (Exception e){ e.printStackTrace(); } //5.獲取到method的執行結果,通過response返回出去 // response.getWriter().write(); } 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; } } }

總結:委派模式在spring中應用十分廣泛,但是它本身不屬於23種經典設計模式。