設計模式之委派模式,大名鼎鼎的Spring都在用

  • 2020 年 3 月 15 日
  • 筆記

什麼是委派模式

雖然說委派模式不屬於Gof23中設計模式,但這並不影響它成為一種經典的設計模式。

「委派」字面意思就是指派一件事情給某人。類比到生活中的場景,比如項目leader指派開發任務給下面的猿猿們。這聽起來有點像靜態代理,不過還是不一樣的,你品,你細品!代理強調的是過程,主要是要在代理過程中加入一些動作的,而委派主要是分配和分發。

代碼實現

我們先新建一個業務處理接口BusinessService

public interface BusinessService {      void doService();  }

新建兩個實現類LoginService和OrderService

public class LoginService implements BusinessService{      public void doService() {          System.out.println("處理登錄相關業務");      }  }    public class OrderService implements BusinessService{      public void doService() {          System.out.println("訂單業務模塊");      }  }

新建一個枚舉類,表示不同的業務類型,這裡假設就兩個,login和order

public enum ServerType {      LOGIN,ORDER;  }

新建一個業務查找類,主要是用於根據不用的業務類型選擇不同的業務組件提供服務。

public class BussinessLookup {      private OrderService orderService;        private LoginService loginService;        /**       * 查找對應的服務       * @param serverType       * @return       */      public BusinessService getBusinessService(ServerType serverType){          if(serverType.equals(ServerType.LOGIN)){              return loginService;          }else{              return orderService;          }      }        public void setOrderService(OrderService orderService) {          this.orderService = orderService;      }        public void setLoginService(LoginService loginService) {          this.loginService = loginService;      }  }

接下來,關鍵的類來了,委派類。做的工作主要是分發。

public class BusinessDelegate {      private BussinessLookup bussinessLookup;        private BusinessService businessService;        private ServerType serverType;        public void setBussinessLookup(BussinessLookup bussinessLookup) {          this.bussinessLookup = bussinessLookup;      }        public void setServerType(ServerType serverType) {          this.serverType = serverType;      }        /**       * 委派方法,其實最終調用的是業務類的方法       */      public void doTask(){          businessService = bussinessLookup.getBusinessService(serverType);          businessService.doService();      }  }

我們再來個客戶端類,也就是請求類,它通過委派類完成工作。就是說我不需要知道在幕後到底是哪個業務組件在處理,我只需要給你請求,你幫我完成好任務就OK.。說明白點,委派類就是做了一層封裝和抽象,不將業務處理的大量組件暴露給請求層或者說是視圖層。

public class Client {      private BusinessDelegate businessDelegate;        public Client(BusinessDelegate businessDelegate) {          this.businessDelegate = businessDelegate;      }        public void doTask(){          businessDelegate.doTask();      }  }

好了,我們寫個Main測試一下。

public class AppMain {      public static void main(String[] args) {          BusinessDelegate businessDelegate = new BusinessDelegate();          BussinessLookup bussinessLookup = new BussinessLookup();          bussinessLookup.setLoginService(new LoginService());          bussinessLookup.setOrderService(new OrderService());            businessDelegate.setBussinessLookup(bussinessLookup);          businessDelegate.setServerType(ServerType.LOGIN);          Client client = new Client(businessDelegate);          client.doTask();    //        businessDelegate.setServerType(ServerType.ORDER);  //        client.doTask();      }  }

結果:

處理登錄相關業務

在這裡,非常有必要看下類圖

在這裡插入圖片描述

在Spring源碼中應用

在Spring源碼中我們可以搜索一下,使用delegate關鍵詞模糊查找下,但凡以Delegate結尾的都是委派模式的應用。

比如:BeanDefinitionParserDelegate、ConstructorDelegate、MultipartResolutionDelegate、TypeConverterDelegate等。

當然了,我們熟知的DispatcherServlet 雖然沒帶delegate,但也是委派模式的一種實現。

前端請求都統一走到DispatcherServlet 的doService()方法中,然後在doService()方法中調用doDispatch()方法,在doDispatch()方法中,會獲取業務處理的handler,執行handle()方法處理請求。

doDispatch()方法核心源碼截圖

doDispatch

應用場景

  1. 當你要實現表現層和業務層之間的松耦合的時候。
  2. 當你想要編排多個服務之間的調用的時候。
  3. 當你想要再封裝一層服務查找和調用時候

公眾號:二營長的筆記
免費領資料:公眾號內回復「二營長」