职责链模式

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

这种场景我们可以用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包,这个也很实用,它用来描述一个顺序处理的过程,有兴趣可以看一看。

posted @   OKevin  阅读(605)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示