1、博客内容均出自于咕泡学院架构师第三期
2、架构师系列内容:架构师学习笔记(持续更新)
负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。不属于GOF 232种设计模式之一。属于行为型模式。
委派模式跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。
委派模式在spring 中应用非常多,最常用的DispatcherServlet 其实就是用到了委派模式。
应用场景:
优缺点:
优点:对内隐藏实现, 易于扩展; 简化调用。
缺点:和静态代理的一样,当如果员工和leader类拓展的时候容易膨胀,难于管理。
现实生活中的一个简单例子。老板(boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工作进度和结果给老板。
下面是一个简单的模型图:
根据模型图来编写代码
首先创建IEmployee员工接口。定义一个执行的方法:
package com.jarvisy.demo.pattern.delegate.simple;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 20:56
* @description :
*/
public interface IEmployee {
public void doing(String command);
}
创建员工A,员工B 分别擅长做加密,架构的工作:
package com.jarvisy.demo.pattern.delegate.simple;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 20:59
* @description :
*/
public class EmployeeA implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工A,我擅长做加密,我现在开始干" + command + "工作"); }
}
package com.jarvisy.demo.pattern.delegate.simple;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 20:59
* @description :
*/
public class EmployeeB implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工B,我擅长做架构,我现在开始干" + command + "工作"); }
}
接着创建Leader类,了解员工的擅长方面,并且持有员工的引用,方便给员工下达执行命令:
package com.jarvisy.demo.pattern.delegate.simple;
import java.util.HashMap;
import java.util.Map;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 20:56
* @description :
*/
public class Leader {
// leader 需要预先知道每个员工的特产,特征,分发任务
private Map<String, IEmployee> target = new HashMap<>();
public Leader() {
target.put("加密", new EmployeeA());
target.put("架构", new EmployeeB());
}
//项目经理自己不干活
public void doing(String command) {
target.get(command).doing(command);
}
}
最后再创建Boss类,给Leader下达任务命令:
package com.jarvisy.demo.pattern.delegate.simple;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 20:55
* @description :
*/
public class Boss {
public void command(String command,Leader leader){
leader.doing(command);
}
}
创建测试类:
package com.jarvisy.demo.pattern.delegate.simple;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 21:04
* @description :
*/
public class DelegateSimpleTest {
public static void main(String[] args) {
Boss boss = new Boss();
boss.command("加密", new Leader());
}
}
类图:
客户请求(Boss)、委派者(Leader)、被被委派者(Target),委派者要持有被委派者的引用。
代理模式注重的是过程, 委派模式注重的是结果。
策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用。
委派的核心:就是分发、调度、派遣。
委派模式:就是静态代理和策略模式一种特殊的组合。
通过代码简单还原一下DispatcherServlet是如何实现委派模式的。
首先创建三个Controller,并各自顶一个方法,模拟我们经常使用的Controller控制器:
package com.jarvisy.demo.pattern.delegate.mvc;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 21:51
* @description :
*/
public class MemberController {
public void getMemberById(String mid){
}
}
package com.jarvisy.demo.pattern.delegate.mvc;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 21:51
* @description :
*/
public class OrderController {
public void getOrderById(String mid){
}
}
package com.jarvisy.demo.pattern.delegate.mvc;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 21:51
* @description :
*/
public class SystemController {
public void logout(){
}
}
接着我们我们创建DispatcherServlet 继承HttpServlet 重写service方法:
package com.jarvisy.demo.pattern.delegate.mvc;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author :Jarvisy
* @date :Created in 2020/9/18 21:48
* @description :相当于Leader的职能
*/
public class DispatcherServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//完成调度
doDispatch(req,resp);
}
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String uri =req.getRequestURI();
String mid = req.getParameter("mid");
//此段代码可以用策略模式进行优化 后续在策略模式学习中优化
if ("getMemberById".equals(uri)){
new MemberController().getMemberById(mid);
}else if ("getMemberById".equals(uri)){
new OrderController().getOrderById(mid);
}else if ("getMemberById".equals(uri)){
new SystemController().logout();
}else {
resp.getWriter().write("404 Not Found !!!");
}
}
}
此时就是一个完整的委派模式,只不过SpringMVC的委派模式远比这个要复杂。Spring中其他运用到委派模式的还有很多,只要以Delegate结尾的都是实现了委派模式的。比如BeanDefinitionParserDelegate 根据不同类型委派不同逻辑解析BeanDefinition。
DispatcherServlet 的doDispatch方法可以使用策略模式去掉if判断逻辑
优化代码见策略模式:https://blog.csdn.net/weixin_38024782/article/details/108675976