设计模式——委派模式

2023-06-09  本文已影响0人  Qiansion齐木楠雄

委派模式

在设计模式中,似乎没有委派模式这一模式,就想鲁迅说的,世界上本么没有路,走的人多了便成了路。正是因为这种逻辑被多次用到,便被前人总结为委派设计模式。
委派模式(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());
    }
}

我擅长加密:我正在做:加密

类图

image.png

从类图中可以看出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);
        }
    }
}  
上一篇 下一篇

猜你喜欢

热点阅读