委派模式
在设计模式中,似乎没有委派模式这一模式,就想鲁迅说的,世界上本么没有路,走的人多了便成了路。正是因为这种逻辑被多次用到,便被前人总结为委派设计模式。
委派模式(Delegate Pattern)的作用就是负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理注重过程,而委派模式注重结果。
委派模式跟我们程序员的生态圈非常像,需求来了,项目经理根据程序员的能力来进行分配,这个的过程就是委派,对于提出需求的人来说,我们程序员是不可见的。
举一个简单的例子
1、创建程序员接口和程序员
public interface Employee {
void doing(String command);
}
public class ProgramerA implements Employee{
@Override
public void doing(String command){
System.out.println("我擅长加密:我正在做:"+command);
}
}
public class ProgramerB implements Employee{
@Override
public void doing(String command){
System.out.println("我擅长架构:我正在做:"+command);
}
}
2、创建项目经理
public class Leader {
// 预先知道每个员工的特长、特征、分发任务
Map<String,Employee> register = new HashMap<>();
public Leader(){
register.put("加密",new ProgramerA());
register.put("架构",new ProgramerB());
}
public void doing(String command){
register.get(command).doing(command);
}
}
3、创建甲方用户,用户只与leader联系
public class Customer {
public void command(String command, Leader leader){
leader.doing(command);
}
}
4、测试
用户有一个加密任务交给项目经理,项目经理进行委派
public class AppTest {
public static void main(String[] args) {
new Customer().command("加密",new Leader());
}
}
我擅长加密:我正在做:加密
类图
从类图中可以看出Leader是作为中间人协调用户的任务和程序员的工作的。而且类图中也提现了与静态代理的区别,Leader只是依赖接口,并不继承接口。一般地,带有delegate或者dispatcher都可以先联想委派模式。
比如我们熟悉的DispatherServlet,SpringMVC中负责请求分发处理的,我们只需关注它的dispatch方法
doDispatch() 方法进行请求分发处理,doDispatch() 方法的主要过程是通过 HandlerMapping 获取 Handler,再找到用于执行它的 HandlerAdapter,执行 Handler 后得到 ModelAndView ,ModelAndView 是连接“业务逻辑层”与“视图展示层”的桥梁,接下来就要通过 ModelAndView 获得 View,再通过它的 Model 对 View 进行渲染。想深入研究DispatcherServlet可以去看这篇文章,写的很好DispatcherServlet详解
这里可以关注第21行,这里就是委派模式的体现
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
// 获取当前请求的WebAsyncManager,如果没找到则创建并与请求关联
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 检查是否有 Multipart,有则将请求转换为 Multipart 请求
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 遍历所有的 HandlerMapping 找到与请求对应的 Handler,并将其与一堆拦截器封装到 HandlerExecution 对象中。
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 遍历所有的 HandlerAdapter,找到可以处理该 Handler 的 HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 处理 last-modified 请求头
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 遍历拦截器,执行它们的 preHandle() 方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
try {
// 执行实际的处理程序
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
// 遍历拦截器,执行它们的 postHandle() 方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
dispatchException = ex;
}
// 处理执行结果,是一个 ModelAndView 或 Exception,然后进行渲染
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
} catch (Exception ex) {
} catch (Error err) {
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// 遍历拦截器,执行它们的 afterCompletion() 方法
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
return;
}
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}