Java设计模式——委派模式

概述

委派模式主要用于任务分发调度派遣。委派者是连接任务执行者和调用者媒介。既然媒介它必然需要包含所有执行者的引用对象,在根据调用者的输入选择适当的执行者去执行,委派和代理模式中的静态代理有很多相似的地方,持有执行者的对象引用,具体业务都是执行者来执行。

模拟场景

一个作业接口

  1. public interface Job {
  2. void homeWork(String type);
  3. }

两门功课实现作业接口

  1. public class English implements Job {
  2. @Override
  3. public void homeWork(String type) {
  4. System.out.println("需要完成 "+type+"的家庭作业!");
  5. }
  6. }
  1. public class Math implements Job {
  2. @Override
  3. public void homeWork(String type) {
  4. System.out.println("需要完成 "+type+"的家庭作业!");
  5. }
  6. }

老师实现作业接口,指派不同类型作业

  1. public class Teacher implements Job{
  2. private Map<String,Job> map=new HashMap<>();
  3. public Teacher() {
  4. map.put("English",new English());
  5. map.put("Math",new Math());
  6. }
  7. @Override
  8. public void homeWork(String type) {
  9. map.get(type).homeWork(type);
  10. }
  11. }

学生测试

  1. /**以下为输出结果
  2. * 需要完成 English的家庭作业!
  3. * 需要完成 Math的家庭作业!
  4. */
  5. public class StudentTest {
  6. public static void main(String[] args) {
  7. new Teacher().homeWork("English");
  8. new Teacher().homeWork("Math");
  9. }
  10. }

总结

从刚才的例子可以看出来委派模式的优点在于封装多个执行者做的事情,使调用者不用关心每个执行者是干嘛的,我这个需求究竟该提给谁,只需要对接委派类就可以了。对没错,就是老师给一堆学生指派作业,不需要管给哪一个学生写什么样的作业,只需要英语老师给英语作业就行。

每当新增的执行者委派类还需要增加新的关系映射,所以我们分析DispatcherServlet是怎么做的。spring容器启动的时候会获取所有@Controller/@Restcontroller的类将url和方法初始化到handlerMappings中,请求来的时候去循环匹配,在利用反射调用具体的方法实现,这样就做到了委派类和执行类的解耦,设计比较巧妙与高级。

对比

委派模式有很多其他设计模式的影子,有点像代理(包含被代理的对象的引用)加策略(分装算法,输入与对应执行者的映射关系)。

与代理模式的区别主要是在业务的侧重点不同。比如前面说了委派注重的是分发调度派遣,代理的目的是通过代理增强被代理的功能,封装一些公共的逻辑。举个例子:古代的媒婆一般知道谁家的孩子什么年龄,你说向他提出要求,让他介绍女孩子给你认识,他会从自己的认知里找个一个和你要求最匹配的人,这就是委派模式。当你们相处的不错,最后要求媒婆去提亲了,这就是代理,娶老婆的是你,但是操办婚事的前前后后(对应代理模式的前增强后增强等)。