設計模式之委派模式(不屬於23種經典設計模式之一)
阿新 • • 發佈:2019-02-11
介紹
標準定義:委派模式的原理為類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種經典設計模式。