专栏首页余林丰职责链模式

职责链模式

所谓职责链模式,其实在现实中非常常见,比如你要提出一个申请,首先可能通过你的组长,你的组长没有权力审批时会上报到经理,经理没有权力审批时上报到总监,总监没有没有权力审批时上报到总经理等等,以此类推直到有权力的管理者来审批。

这种场景我们可以用if-else判断分支来实现,不过记住大量的if-else判断分支并不是一个好的设计,此时我们可以采用“职责链模式”来解决。

首先不管领导是谁,他们都是管理者,那么我们抽象出一个管理者公共抽象类,如下图所示:

职责链模式中有很重要的一点就是,当该处理类没有权限不能处理此请求时需要将请求传递给下一个处理类,以此类推,直到有权限处理类处理该请求时即停止将请求传递给下一个处理类。所以我们画出职责链模式的UML类结构图。

同样我们用代码来实现,定义一个Handler抽象类,其中有一个具体方法是设置处理类的后继者,这样才能实现当一个具体的处理类不能处理该请求时将请求转发给它的后继者,还有一个抽象方法是其各个派生类实现自己的处理方法。

 1 package day_9_chain;
 2 
 3 /**
 4  * 抽象处理公共类
 5  * @author 余林丰
 6  *
 7  * 2016年10月10日
 8  */
 9 public abstract class Handler {
10     protected Handler handler;
11     
12     public void setNextHandler(Handler handler){
13         this.handler = handler;
14     }
15     
16     public abstract void request(int request);
17 }

接下来是3个具体的处理类。

 1 package day_9_chain;
 2 
 3 /**
 4  * 具体处理类1
 5  * @author 余林丰
 6  *
 7  * 2016年10月10日
 8  */
 9 public class ConcreteHandler1 extends Handler {
10 
11     /* (non-Javadoc)
12      * @see day_9_chain.Handler#request(int)
13      */
14     @Override
15     public void request(int request) {
16         if (request >=0 && request <= 10){
17             System.out.println("ConcreteHandler1处理请求:" + request);
18         } else if (handler != null){
19             handler.request(request);
20         }
21     }
22 
23 }
 1 package day_9_chain;
 2 
 3 /**
 4  * 具体处理类2
 5  * @author 余林丰
 6  *
 7  * 2016年10月10日
 8  */
 9 public class ConcreteHandler2 extends Handler {
10 
11     /* (non-Javadoc)
12      * @see day_9_chain.Handler#request(int)
13      */
14     @Override
15     public void request(int request) {
16         if (request > 10 && request <= 20){
17             System.out.println("ConcreteHandler2处理:" + request);
18         } else if (handler != null){
19             handler.request(request);
20         }
21     }
22 
23 }
 1 package day_9_chain;
 2 
 3 /**
 4  * 具体处理类3
 5  * @author 余林丰
 6  *
 7  * 2016年10月10日
 8  */
 9 public class ConcreteHandler3 extends Handler {
10 
11     /* (non-Javadoc)
12      * @see day_9_chain.Handler#request(int)
13      */
14     @Override
15     public void request(int request) {
16         if (request > 20 && request <= 30){
17             System.out.println("ConcreteHandler3处理:" + request);
18         } else if (handler != null){
19             handler.request(request);
20         }
21     }
22 
23 }

客户端测试代码。

 1 package day_9_chain;
 2 
 3 /**
 4  * @author 余林丰
 5  *
 6  * 2016年10月10日
 7  */
 8 public class Client {
 9 
10 
11     public static void main(String[] args) {
12         ConcreteHandler1 concreteHandler1 = new ConcreteHandler1();
13         ConcreteHandler2 concreteHandler2 = new ConcreteHandler2();
14         ConcreteHandler3 concreteHandler3 = new ConcreteHandler3();
15         
16         concreteHandler1.setNextHandler(concreteHandler2);
17         concreteHandler2.setNextHandler(concreteHandler3);
18         
19         concreteHandler1.request(25);
20         
21     }
22 
23 }

我们可以看到职责链的好处在于:当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。它们仅需保持一个指向其后继者的引用,而且并不需要保持它后面所有后继者的引用。和这个职责链模式类似的还有一个东西叫做“链处理”,需要导入一个叫做commons-chain的jar包,这个也很实用,它用来描述一个顺序处理的过程,有兴趣可以看一看。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 工厂模式——抽象工厂模式(+反射)

    这里又出现了一个抽象工厂模式,这个抽象工厂模式又是什么呢? 我们现在来模拟一个场景,现在用的是Mysql数据库,明天让你更换为Oracle数据库。此时,想想要做...

    用户1148394
  • 代理模式

    代理模式,在UML类结构上很好理解, 不过在实际应用当中可能并不是很清楚代理模式应用在哪些场景里。这里给出《大话设计模式》中对代理模式应用场合的解释: 第一,远...

    用户1148394
  • Spring中老生常谈的FactoryBean

    FactoryBean和BeanFactory由于在命名上极其相似,一直以来困扰了不少的开发者。

    用户1148394
  • Pandas数据处理——一文详解数据拼接方法merge

    为了方便维护,一般公司的数据在数据库内都是分表存储的,比如用一个表存储所有用户的基本信息,一个表存储用户的消费情况。所以,在日常的数据处理中,经常需要将两张表拼...

    数据森麟
  • 是时候忘掉finalize方法了

    故事要从jdk11 early access版说起。 近日,发现jdk11发布了一个早鸟版。心想,jdk10刚刚发布没多久(JDK10要来了:下一代 Java...

    ImportSource
  • 最新考研调剂信息全面获取!Python帮你一手掌握

    【导语】:今天我们聊聊如何获取考研调剂数据,Python技术部分可以直接看第三部分。

    CDA数据分析师
  • 近半数白领租房住,超7成加班没补贴,这份报告里有你么?

    导读:在这个跳槽旺季,《2019年白领生活状况调研报告》从白领的生活、健康、社交、职场等四个方面出发,对11024名职场人士进行了问卷调查,让我们对于白领们的生...

    华章科技
  • P1850 换教室

    题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程。 在可以选择的课程中,有  节课程安排在 nn 个时间段上。在第  ...

    attack
  • Spillable StateBackend 之 HeapStatusMonitor 解析

    Flink 社区的 Spillable Backend 特性,社区经过了大半年的开发,目前已经放出了预览版可供体验。

    KyleMeow
  • Springboot之AbstractApplicationEventMulticaster

      Springboot的版本2.0.9.release,对应的SpringFramework值5.0.x.release。

    克虏伯

扫码关注云+社区

领取腾讯云代金券