委派模式(Delegate Pattern)不属于GoF 23种设计模式。委派模式的基本作用就是负责任务的调用和分配,跟代理模式很像,可以看作一种特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在Spring中应用得非常多,大家常用的DispatcherServlet就用到了委派模式。现实生活中也常有委派的场景发生,例如老板(Boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发任务,待员工把任务完成后,再由项目经理向老板汇报结果。我们用代码来模拟一下这个业务场景,先来看一下类图,如下图所示。(书中原话)
模拟下,首先是IEmployee员工接口:
package nju.java.pattern.delegate_pattern.simple;
public interface IEmployee {
public void doing(String command);
}
员工类A、B
package nju.java.pattern.delegate_pattern.simple;
public class EmployeeA implements IEmployee {
public void doing(String command) {
System.out.println("我是员工A,我现在开始干"+command+"工作");
}
}
package nju.java.pattern.delegate_pattern.simple;
public class EmployeeB implements IEmployee{
public void doing(String command) {
System.out.println("我是员工B,我现在开始干"+command+"工作");
}
}
项目经理类Leader:
package nju.java.pattern.delegate_pattern.simple;
import java.util.HashMap;
import java.util.Map;
public class Leader implements IEmployee {
private Map targets=new HashMap();
public Leader(){
targets.put("加密",new EmployeeA());
targets.put("登录",new EmployeeB());
}
public void doing(String command) {
targets.get(command).doing(command);
}
}
Boss类:
package nju.java.pattern.delegate_pattern.simple;
public class Boss {
public void command(String command,Leader leader){
leader.doing(command);
}
}
测试代码:
package nju.java.pattern.delegate_pattern.simple;
public class DelegateTest {
public static void main(String[] args) {
//代理模式注重的是过程,委派模式注重的是结果
//策略模式注重可扩展性(外部扩展性),委派模式注重内部的灵活性和可复用性
//委派模式的核心就是分发、调度、派遣,委派模式是静态代理和策略模式的一种特殊组合
new Boss().command("登录",new Leader());
}
}
简易还原下DispatchServlet如何实现委派模式的,随便写几个Controller:
package nju.java.pattern.delegate_pattern.mvc.controller;
public class MemberController {
public void getMemberById(String mid){
}
}
package nju.java.pattern.delegate_pattern.mvc.controller;
public class OrderController {
public void getOrderById(String mid){
}
}
package nju.java.pattern.delegate_pattern.mvc.controller;
public class SystemController {
public void logout(){
}
}
DispatchServlet类:
package nju.java.pattern.delegate_pattern.mvc.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
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();
}
}
}
在Spring源码中,以Delegate结尾的地方都实现了委派模式。
另外具体DispatchServlet干了什么可以看看下面这个博客:
https://www.jianshu.com/p/4ebaf6230b6b
代码位置:https://github.com/YellowDii/MySpring.git
参考书籍:《Spring5核心原理与30个类手写实现》