Spring源码学习笔记:经典设计模式之委派模式

1、博客内容均出自于咕泡学院架构师第三期
2、架构师系列内容:架构师学习笔记(持续更新)

0、委派模式(Delegate Pattern)

负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。不属于GOF 232种设计模式之一。属于行为型模式。
委派模式跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。
委派模式在spring 中应用非常多,最常用的DispatcherServlet 其实就是用到了委派模式。

应用场景:

  1. 当你要实现表现层和业务层之间的松耦合的时候。
  2. 当你想要编排多个服务之间的调用的时候。
  3. 当你想要再封装一层服务查找和调用时候。

优缺点:
优点:对内隐藏实现, 易于扩展; 简化调用。
缺点:和静态代理的一样,当如果员工和leader类拓展的时候容易膨胀,难于管理。

1、委派模式图形示例

现实生活中的一个简单例子。老板(boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工作进度和结果给老板。
下面是一个简单的模型图:
Spring源码学习笔记:经典设计模式之委派模式_第1张图片
根据模型图来编写代码
首先创建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());
    }
}

类图:
Spring源码学习笔记:经典设计模式之委派模式_第2张图片
客户请求(Boss)、委派者(Leader)、被被委派者(Target),委派者要持有被委派者的引用。
代理模式注重的是过程, 委派模式注重的是结果。
策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用。
委派的核心:就是分发、调度、派遣。
委派模式:就是静态代理和策略模式一种特殊的组合。

2、SpringMVC 中委派模式的应用

通过代码简单还原一下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

你可能感兴趣的:(java设计模式,Spring源码学习笔记,架构师学习笔记,java,设计模式,spring)