定义
委派模式是指两个对象参与处理同一个请求,接收请求的对象将请求委托给另一个对象来处理。它的基本作用就是负责任务的调度和分派任务。跟代理模式很像, 但是代理模式注重过程, 而委派模式注重结果。
应用场景
委派模式主要用于消除程序中大量的if…else…和switch语句。
模拟场景
UML类结构图
代码实现
Boss 类
public class Boss {
public void command(String command, Leader leader) {
leader.doing(command);
}
}
Leader 类
public class Leader {
/**
* 预先知道每个员工的特长、特征,分发任务
*/
private Map<String, IEmployee> register = new HashMap<>();
public Leader() {
register.put("加密", new EmployeeA());
register.put("架构", new EmployeeB());
}
public void doing(String command) {
register.get(command).doing(command);
}
}
IEmployee 类
public interface IEmployee {
/**
* 执行
* @param command 命令
*/
void doing(String command);
}
EmployeeA 类
public class EmployeeA implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工A,我开始干活了,擅长加密,执行:" + command);
}
}
EmployeeB 类
public class EmployeeB implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工B,我开始干活了,擅长架构,执行:" + command);
}
}
测试类
public class DelegateTest {
public static void main(String[] args) {
new Boss().command("加密", new Leader());
}
}
输出结果
我是员工A,我开始干活了,擅长加密,执行:加密
在源码中的体现
在Spring的DispatcherServlet中就使用了委派模式, 通过对委派模式的使用, 根据请求路径的不同, 将不同的路径
UML类图
代码实现
DispatcherServlet 类
public class DispatcherServlet extends HttpServlet {
/**
* 预先知道每个controller有哪些 方法
*/
private Map<String, Object> register = new HashMap<>();
public DispatcherServlet() {
register.put("getMemberById", new MemberController());
register.put("getOrderById", new OrderController());
register.put("logout", new SystemController());
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 完成调度
try {
doDispatch(req, resp);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws IOException, InvocationTargetException, IllegalAccessException {
String uri = req.getRequestURI();
String mid = req.getParameter("mid");
Object controller = register.get(uri);
Class<?> clazz = controller.getClass();
List<String> methodNames = Arrays.asList(controller.getClass().getDeclaredMethods()).stream().map(m -> m.getName()).collect(Collectors.toList());
if (methodNames.contains(uri)) {
List<Method> declaredMethods = Arrays.asList(clazz.getDeclaredMethods());
for (Method method : declaredMethods) {
System.out.println("方法名:" + method.getName());
if (uri.equals(method.getName())) {
method.invoke(controller, mid);
}
}
} else {
resp.getWriter().write("404 Not Found!");
}
}
}
MemberController 类
public class MemberController {
public void getMemberById(String mid) {
System.out.println("getMemberById, mid=" + mid);
}
}
OrderController 类
public class OrderController {
public void getOrderById(String mid) {
System.out.println("getOrderById, mid=" + mid);
}
}
SystemController 类
public class SystemController {
public void logout() {
System.out.println("logout");
}
}