一、委派模式的定义及应用场景
委派模式(Delegate Pattern)的基本作用是负责任务的调用和分配,跟代理模式很像,可以看做特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在Spring中的应用很多,比如:DispatcherServlet。用现实中的案例就是:老板给项目经理下达任务,项目经理再分配任务给员工,员工完成任务后,再由项目经理向老板汇报。
创建IEmployee员工接口:
public interface IEmployee { void doing(String command); }
创建员工A,B:
public class EmployeeA implements IEmployee { @Override public void doing(String command) { System.out.println("I'm A ,我在做" + command); } } public class EmployeeB implements IEmployee { @Override public void doing(String command) { System.out.println("I'm B ,我在做" + command); } }
创建项目经理:
public class Leader implements IEmployee { private Map<String, IEmployee> targets = new HashMap<>(); public Leader() { targets.put("加密", new EmployeeA()); targets.put("登录", new EmployeeB()); } //项目经理自己不干活 @Override public void doing(String command) { targets.get(command).doing(command); } }
创建老板:
public class Boss { public void command(String command, Leader leader) { leader.doing(command); } }
创建测试类:
public class DelegateTest { public static void main(String[] args) { new Boss().command("登录", new Leader()); } }
委派模式注重的是结果,代理模式注重的是过程。
委派模式注重内部的灵活和可复用性,策略模式注重可扩展性(外部扩展性)。
委派模式的核心是分发、调度、派遣,委派模式是静态代理和策略模式的一种特殊组合。
二、委派模式在源码中的体现
来看一下Spring MVC中的DispatherServlet是如何实现委派模式的。先创建两个Controller:
@RestController @RequestMapping("/order") public class OrderController { @RequestMapping(value = "/getOrderById", method = RequestMethod.POST) public void getOrderById(String mid) { } }
@RestController @RequestMapping("/member") public class MemberController { @RequestMapping(value = "/getMemberById", method = RequestMethod.POST) public void getMemberById(String mid){ } }
分发任务,相当于项目经理:
public class DispatcherServlet extends HttpServlet { private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { String uri = request.getRequestURI(); String mid = request.getParameter("mid"); if ("/member/getMemberId".equals(uri)) { new MemberController().getMemberById(mid); } else if ("/order/getOrderById".equals(uri)) { new OrderController().getOrderById(mid); } else { response.getWriter().write("404 Not Found!"); } } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { doDispatch(request, response); } catch (Exception e) { e.printStackTrace(); } } }
这个简单的委派模式应用就实现了,在Spring中还有很多用到委派模式,在源码中以Delegate结尾的地方就是实现了委派模式,例如:BeanDefinitionParserDelegate根据不同逻辑委派不同的逻辑解析BeanDefinition.