委派模式不屬於GoF 23種設計模式。委派模式的基本作用就是負責任務的派遣和調用,跟代理模式很像,可以看成一種特殊情況下的靜態的全權代理。但是,代理模式注重過程,委派模式注重結果。委派模式在Spring種的應用場景非常多,我們最熟悉的DispatcherServlet就用到了委派模式。文中會簡單模仿下DispatcherServlet的實現。
在現實生活中也常有委派模式的發生場景,如 Boss 給 Leader 下達任務,Leader 會根據實際情況給每個 coder 下發任務,等每個 coder 完成任務之後,leader 再把結果回報給 boss 。在此過程中 boss 只關心任務的完成情況,而不會關注 是哪個 coder 完成的哪個任務。下面就用一個簡單的例子來說明委派模式:
1、創建 Employee 接口
public interface Employee {
public void code(String command);
}
2、創建碼農A
public class CoderA implements Employee {
@Voerride
public void code(String command){
System.out.println("我是 CodeA ,我工作內容是" + command );
}
}
3、創建碼農B
public class CoderB implements Employee {
@Voerride
public void code(String command){
System.out.println("我是 CodeB ,我工作內容是" + command );
}
}
4、創建Leader
public class Leader implements Employee {
// 可以看成任務中心
Map<String,Employee> tasks = new HashMap<String,Employee>();
public Leader {
tasks.put("加密",new CoderA());
tasks.put("登錄",new CoderB());
}
// leader 自己是不幹活的,任務或發配給每個 coder
@Voerride
public void code(String command){
tasks.get(command).code(command);
}
}
5、創建BOSS類,下達任務
public class Boss {
// 下達工作指令
public void command(String command,Leader leader){
leader.code(command);
}
}
6、測試結果
public class Test {
public static void main (String[] args){
// 創建 Boss 實例
Boss boss = new Boss();
// 創建 Leader 實例
Leader leader = new Leader();
// 給 Leader 下發任務
boss.command("登錄",leader);
}
}
控制檯輸出:
我是 CodeB ,我的工作內容是登錄
由上述的小例子,應該可以看到, Boss 只對 Leader 下達命令,並沒有直接給 Code 分配任務,分配任務由 Leader 來做。也就是說 Boss 委派 Leader 來 分配任務。
DispatcherServlet
下面模仿 Spring MVC 中 DispatcherServlet 的實現:
1、先創建一個業務類 MemberController
public class MemberController {
public Object getMemberById(String mid) {
...
}
}
2、創建一個訂單類 OrderController
public class OrderController {
public Object getOrderById(String oid) {
...
}
}
3、創建一個 SystemController
public class SystemController {
public Object login() {
...
}
public Object logout() {
...
}
}
4、創建 DispatcherServlet 類
public class DispatcherServlet extends HttpServlet{
public doDispatch(HttpServletRequest request, HttpServletRqsponse response){
// 獲取請求地址
String uri = request.getRequestURI();
// 獲取請求參數
String id = request.getParameter("id");
if("getMemberById".equals(uri)){
new MemberController().getMemberById(id);
}else if("getOrderById".equals(uri)){
new OrderController().getOrderById(id);
}else if("login".equals(uri)){
new SystemController().login();
}else if("logout".equals(uri)){
new SystemController().logout();
}else{
response.getWriter().write("404 Not Found !");
}
}
protected void service(HttpServletRequest req, HttpServletRqsponse res){
try{
doDispatch(req,res);
}catch(Exception e){
e.printStackTrace();
}
}
}
5、web.xml 中的配置:
<servlet>
<servlet-name>servlet</servlet>
<!-- 以下爲之前創建的 DispatcherServlet 的全限定名 -->
<servlet-class>*.DispatcherServlet</servlet-class>
<!-- 加載時啓動 -->
<load-on-startup>1</load-on-startup>
<servlet>
<servlet-mapping>
<servlet-name>servlet</servlet>
<url-pattern>/*</url-pattern>
</servlet-mapping>
以上就實現了 Spring MVC 中分發路由的功能,在真正的框架中的實現肯定不是寫死的,而是根據反射獲取所有的 uri ,在訪問時進行匹配,DispatcherServlet 的功能就是對請求進行分發,路由到對應的方法中。當然在 Spring 中還有很多 委派模式,以 Delegate 結尾的地方都實現了委派模式,有時間可以去了解一下。