设计模式 | 挑战委派模式


theme: vue-pro

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

委派模式,它不属于GOF23种常见模式,它允许对象组合实现与继承相同的代码重用。

一、定义

委派是一种使组合具有与继承一样强大的复用能力的方法。在委派中,处理请求涉及两个对象: 接收对象将操作委派给其委派对象,这类似于将请求延迟到父类的子类。

委派模式代理模式很相似,可以看做是一种特殊情况下的静态代理的全权代理。两种模式有本质的区别,代理模式注重过程,而委派模式注重结果。

两者的区别说的很抽象,具体来说:

  • 委派模式大致的流程是:你找我,我作为中间人,我不干事,我又根据你的需求/命令去找别人处理。这里强调一个权衡选择的过程。
  • 代理模式大致的流程是:你想办一件事情,明确的知道找A就能完成,但是你不找A,你找A的代理人去处理,实际上A的代理人还是去找A去办理的。

委派模式基本的作用就是负责任务的调用和分配任务。在Java生态中,Spring框架就用到了委派模式,哪个地方呢,就是大家熟知的DispatcherServlet。一般来说类名上使用了DelegatingDispathcer单词,大概率也就用到了委派模式。

二、代码实现

这里构想一个干工程的公司,公司里面有Boss、Manager、Worker等角色,Worker具体细分了电工ElectWorker,木工 WoodWorker等。

有一个场景,老板发送个指令给经理,让经理去安排电工或木工的活。

首先要创建工人的抽象接口,接口中包含描述工人的工种性质,以及工人执行干活的操作。

public interface Worker { ​   /**     * 干事的工种类型     * @return 工种类型     */   String workType(); ​   /**     * 干事当然是干事情     */   void doingJob(String command); }

然后具体实现木工和电工。

public class WoodWorker implements Worker{   /**     * 干事的工种类型     *     * @return 工种类型     */   @Override   public String workType() {       return "WoodWorker";   } ​   /**     * 干事当然是干事情     */   @Override   public void doingJob(String command) {       System.out.println("i am WoodWorker,receive command【 " + command + "】,start to work");   } } ​ public class ElectWorker implements Worker{   /**     * 干事的工种类型     *     * @return 工种类型     */   @Override   public String workType() {       return "ElectWorker";   } ​   /**     * 干事当然是干事情     */   @Override   public void doingJob(String command) {       System.out.println("i am ElectWorker,receive command【 " + command + "】,start to work");   } }

管理工人的直接上级是经理。

public class Manager { ​   final Map<String,Worker> scheduler = new HashMap<>(); ​   public Manager(){       scheduler.put(WorkType.WOOD,new WoodWorker());       scheduler.put(WorkType.ELECT,new ElectWorker());   }   public void doing(String command){       scheduler.get(ANALYSIS_WORK_TYPE.apply(command)).doingJob(command);   } ​   /**     * 分析命令的任务类型     */   static final Function<String,String> ANALYSIS_WORK_TYPE = command->{       if(command.contains(WorkType.WOOD)){           return WorkType.WOOD;       }else if(command.contains(WorkType.ELECT)){           return WorkType.ELECT;       }       throw new UnsupportedOperationException();   }; ​   interface WorkType{       String WOOD = "Wood";       String ELECT = "Elect";   } ​ }

经理管理了工人,通过scheduler 进行任务调度,他不是命令/任务的最终执行者,他会根据命令分析具体的任务类型,再安排具体的工人去干活。

管理经理的当然是老板,老板只是需要发号施令给经理,不需要知道任务具体是谁去执行。

public class Boss {   public void command(String command,Manager manager){       manager.doing(command);   } }

执行流程。

public class DelegatingApp {   public static void main(String[] args) {       new Boss().command("anybody Wood",new Manager());       new Boss().command("anybody Elect",new Manager());   } }

执行后输出。

image-20210805152146864.png

整个程序UML类图如下

Delegating.png

三、总结

总的来说,使用委托模式,会让逻辑层次更加分明,各个角色的职责划分更加清晰,代码实现上也会优雅不少。但同时也要注意区分一下代理模式委派模式策略模式三者的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值