前言
委派模式(Delegate Pattern) 不属于Gof23种设计模式,委派模式的基本作用就是负责任务的调度和分配 ,跟代理模式很像,可以看做是一种特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在Spring中应用的非常多,最常见的DispatcherServlet就用到了委派模式。生活中常见的委派场景也有很多,例如老板(Boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发任务,待员工把任务完成,再有项目经理给老板汇报情况。接下来就让我们用代码去模拟这个场景。
提示:以下是本篇文章正文内容,下面案例可供参考
案例一
Boss
public class Boss {
public void doing(String commond, Leader leader) {
leader.doing(commond);
}
}
Leader
public interface IEmployee {
void doing(String commond);
}
员工A
public class EmployeeA implements IEmployee{
@Override
public void doing(String commond) {
System.out.println("我是员工A,现在开始执行"+commond+"任务");
}
}
员工B
public class EmployeeB implements IEmployee{
@Override
public void doing(String commond) {
System.out.println("我是员工B,现在开始执行"+commond+"任务");
}
}
测试代码
public static void main(String[] args) {
//代理模式注重的是过程,委派模式注重的是结果
//策略模式注重的是可扩展性(外部扩展性),委派模式注重内部的灵活性和可用性
//委派模式的核心就是分发,调度,派遣,委派模式是静态代理和策略模式的一种特殊组合
Boss boss = new Boss();
boss.doing("登陆", new Leader());
}
上面就通过委派模式模拟了一个调度分发任务的场景,一定要和代理模式分清楚,代理模式重过程,
委派模式重结果,代理模式的核心在于对目标对象的增强,委派模式核心就是分发,调度,派遣。
可以将委派模式看作是静态代理和策略模式的一种特殊组合
案例二
我们在还原一下SpringMVC中DispatcherServlet如何实现委派模式的。
业务类MemBerController
public class MemberController {
public void getMemberById(String mid) {
System.out.println("委派给MemberController处理请求");
}
}
业务类OrderController
public class OrderController {
public void getOrderById(String id) {
System.out.println("委派给OrderController处理请求");
}
}
业务类SystemController
public class SystemController {
public void logout() {
System.out.println("委派给SystemController处理请求");
}
}
DispatcherServlet调度分发类
public class DispatcherServlet extends HttpServlet {
private void doDispathc(HttpServletRequest request,HttpServletResponse response) throws Exception {
String url = request.getRequestURI();
url = url.substring(url.lastIndexOf("/"));
String mid = request.getParameter("mid");
if ("/getMemberById".equals(url)) {
new MemberController().getMemberById(mid);
} else if ("/getOrderById".equals(url)) {
new OrderController().getOrderById(mid);
} else if ("/logout".equals(url)) {
new SystemController().logout();
}else {
response.getWriter().write("404 Not Found");
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
try {
doDispathc(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>Xzq ServletTest App</display-name>
<servlet>
<servlet-name>delegateServlet</servlet-name>
<servlet-class>com.xzq.pattern.factory.delegate.mvc.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>delegateServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
一个完整的委派模式就出来了,在Spring中还有很多委派模式的实例,我们可以观察以Delegate结尾的地方都使用了委派模式,例如BeanDefinitionParseDelegate根据不同类型委派不同的逻辑解析BeanDefintion。
当然在上述代码中是有一些问题的,我们通过if else来区分逻辑不同,如果业务量上来,Controller增多,if else将会十分繁琐,我们可以使用使用策略模式来与委派模式组合,在下一章节策略模式中我们会进行优化代码。
总结
代理模式是代理对象对目标对象的增强,注重过程 策略模式是封装不同变化算法,选择调用 委派模式核心是分发,调度,派遣,可以看作是一种特殊情况的代理模式+策略模式。学习设计模式不能死搬硬套,各个模式之间的划分总会有些相似之处,因为设计模式殊途同归,所做出来的变化皆是为了演化程序开发中开闭,高内聚,低耦合的思想,所以我们应该抓住各个设计模式中它们的侧重点加以利用。
文章评论