职责链模式(Chain of Responsibility)的Java实现

简介:

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

适用场景:

1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;

3、处理一个请求的对象集合应被动态指定。

通用类图:

在大学里面当班干部,时常要向上级申请各方面的东西。譬如申请全班外出秋游,普通同学将申请表交给班长,班长签字之后交给辅导员,辅导员批准之后上交到主任办公室…就是这样,一个请求(这里是一份申请表)有时候需要经过好几个级别的处理者(这里是辅导员、主任)的审查才能够最终被确定可行与否。

在这里表现出来的是一个职责链,即不同的处理者对同一个请求可能担负着不同的处理方式、权限,但是我们希望这个请求必须到达最终拍板的处理者(否则秋游就没戏了)。这种关系就很适合使用职责链模式了。

类图结构如下:

 代码实现如下:

 
  1. // 全局变量,接口类型  
  2. /**  
  3.  * 使用Java中的interface定义全局变量,可根据具体需要在   
  4.  * 具体的包中使用静态导入相关的全局变量,语法如下:   
  5.  *  import static package01.package02.*;  
  6.  */ 
  7. interface Levels {  
  8.     public static final int LEVEL_01 = 1;  
  9.     public static final int LEVEL_02 = 2;  
  10.     public static final int LEVEL_03 = 3;  

 

 
  1. // 抽象请求类  
  2. abstract class AbstractRequest {  
  3.     private String content = null;  
  4.  
  5.     public AbstractRequest(String content) {  
  6.         this.content = content;  
  7.     }  
  8.  
  9.     public String getContent() {  
  10.         return this.content;  
  11.     }  
  12.  
  13.     // 获得请求的级别  
  14.     public abstract int getRequestLevel();  

 

 
  1. // 具体请求类01  
  2. class Request01 extends AbstractRequest {  
  3.     public Request01(String content) {  
  4.         super(content);  
  5.     }  
  6.  
  7.     @Override 
  8.     public int getRequestLevel() {  
  9.         return Levels.LEVEL_01;  
  10.     }  
  11. }  
  12.  
  13. // 具体请求类02  
  14. class Request02 extends AbstractRequest {  
  15.     public Request02(String content) {  
  16.         super(content);  
  17.     }  
  18.  
  19.     @Override 
  20.     public int getRequestLevel() {  
  21.         return Levels.LEVEL_02;  
  22.     }  
  23. }  
  24.  
  25. // 具体请求类03  
  26. class Request03 extends AbstractRequest {  
  27.     public Request03(String content) {  
  28.         super(content);  
  29.     }  
  30.  
  31.     @Override 
  32.     public int getRequestLevel() {  
  33.         return Levels.LEVEL_03;  
  34.     }  

 

 
  1. // 抽象处理者类,  
  2. abstract class AbstractHandler {  
  3.     // 责任链的下一个节点,即处理者  
  4.     private AbstractHandler nextHandler = null;  
  5.  
  6.     // 捕获具体请求并进行处理,或是将请求传递到责任链的下一级别  
  7.     public final void handleRequest(AbstractRequest request) {  
  8.  
  9.         // 若该请求与当前处理者的级别层次相对应,则由自己进行处理  
  10.         if (this.getHandlerLevel() == request.getRequestLevel()) {  
  11.             this.handle(request);  
  12.         } else {  
  13.             // 当前处理者不能胜任,则传递至职责链的下一节点  
  14.             if (this.nextHandler != null) {  
  15.                 System.out.println("当前 处理者-0" + this.getHandlerLevel()  
  16.                         + " 不足以处理 请求-0" + request.getRequestLevel());  
  17.                   
  18.                 // 这里使用了递归调用  
  19.                 this.nextHandler.handleRequest(request);  
  20.             } else {  
  21.                 System.out.println("职责链上的所有处理者都不能胜任该请求...");  
  22.             }  
  23.         }  
  24.     }  
  25.  
  26.     // 设置责任链中的下一个处理者  
  27.     public void setNextHandler(AbstractHandler nextHandler) {  
  28.         this.nextHandler = nextHandler;  
  29.     }  
  30.  
  31.     // 获取当前处理者的级别  
  32.     protected abstract int getHandlerLevel();  
  33.  
  34.     // 定义链中每个处理者具体的处理方式  
  35.     protected abstract void handle(AbstractRequest request);  

 

 
  1. // 具体处理者-01  
  2. class Handler01 extends AbstractHandler {  
  3.     @Override 
  4.     protected int getHandlerLevel() {  
  5.         return Levels.LEVEL_01;  
  6.     }  
  7.  
  8.     @Override 
  9.     protected void handle(AbstractRequest request) {  
  10.         System.out.println("处理者-01 处理 " + request.getContent() + "\n");  
  11.     }  
  12. }  
  13.  
  14. // 具体处理者-02  
  15. class Handler02 extends AbstractHandler {  
  16.     @Override 
  17.     protected int getHandlerLevel() {  
  18.         return Levels.LEVEL_02;  
  19.     }  
  20.  
  21.     @Override 
  22.     protected void handle(AbstractRequest request) {  
  23.         System.out.println("处理者-02 处理 " + request.getContent()+ "\n");  
  24.     }  
  25. }  
  26.  
  27. // 具体处理者-03  
  28. class Handler03 extends AbstractHandler {  
  29.     @Override 
  30.     protected int getHandlerLevel() {  
  31.         return Levels.LEVEL_03;  
  32.     }  
  33.  
  34.     @Override 
  35.     protected void handle(AbstractRequest request) {  
  36.         System.out.println("处理者-03 处理 " + request.getContent()+ "\n");  
  37.     }  

 

 
  1. // 测试类  
  2. public class Client {  
  3.     public static void main(String[] args) {  
  4.         // 创建指责链的所有节点  
  5.         AbstractHandler handler01 = new Handler01();  
  6.         AbstractHandler handler02 = new Handler02();  
  7.         AbstractHandler handler03 = new Handler03();  
  8.  
  9.         // 进行链的组装,即头尾相连,一层套一层  
  10.         handler01.setNextHandler(handler02);  
  11.         handler02.setNextHandler(handler03);  
  12.  
  13.         // 创建请求并提交到指责链中进行处理  
  14.         AbstractRequest request01 = new Request01("请求-01");  
  15.         AbstractRequest request02 = new Request02("请求-02");  
  16.         AbstractRequest request03 = new Request03("请求-03");  
  17.           
  18.         // 每次提交都是从链头开始遍历  
  19.         handler01.handleRequest(request01);  
  20.         handler01.handleRequest(request02);  
  21.         handler01.handleRequest(request03);  
  22.     }  

测试结果:

 
  1. 处理者-01 处理 请求-01 
  2.  
  3. 当前 处理者-01 不足以处理 请求-02 
  4. 处理者-02 处理 请求-02 
  5.  
  6. 当前 处理者-01 不足以处理 请求-03 
  7. 当前 处理者-02 不足以处理 请求-03 
  8. 处理者-03 处理 请求-03 
在上面抽象处理者 AbstractHandler 类的 handleRequest() 方法中,被 protected 修饰,并且该方法中调用了两个必须被子类覆盖实现的抽象方法,这里是使用了模板方法模式(Template Mehtod)。其实在这里,抽象父类的 handleRequest() 具备了请求传递的功能,即对某些请求不能处理时,马上提交到下一结点(处理者)中,而每个具体的处理者仅仅完成了具体的处理逻辑,其他的都不用理。
 
记得第一次看到职责链模式的时候,我很惊讶于它能够把我们平时在代码中的 if..else.. 的语句块变成这样灵活、适应变化。例如:如果现在辅导员请长假了,但我们的秋游还是要争取申请成功呀,那么我们在 Client 类中可以不要创建 handler02,即不要将该处理者组装到职责链中。这样子处理比 if..else..好多了。或者说,突然来了个爱管闲事的领导,那么我照样可以将其组装到职责链中。
 
关于上面使用场景中提到的3个点:
1、处理者在运行时动态确定其实是我们在 Client 中组装的链所引起的,因为具体的职责逻辑就在链中一一对应起来;
2、因为不确定请求的具体处理者是谁,所以我们把所有可能的处理者组装成一条链,在遍历的过程中就相当于向每个处理者都提交了这个请求,等待其审查。并且在审查过程中,即使不是最终处理者,也可以进行一些请求的“包装”操作(这种功能类似于装饰者模式),例如上面例子中的签名批准;
3、处理者集合的动态指定跟上面的第1、2点类似,即在 Client 类中创建了所有可能的处理者。
 
不足之处:

1、对于每一个请求都需要遍历职责链,性能是个问题;

2、抽象处理者 AbstractHandler 类中的 handleRequest() 方法中使用了递归,栈空间的大小也是个问题。

 个人看法:

职责链模式对于请求的处理是不知道最终处理者是谁,所以是运行动态寻找并指定;而命令模式中对于命令的处理时在创建命令是已经显式或隐式绑定了接收者。



本文转自 xxxx66yyyy 51CTO博客,原文链接:http://blog.51cto.com/haolloyin/342166,如需转载请自行联系原作者

相关文章
|
6月前
|
设计模式 Java
JAVA设计模式16:职责链模式,轻松解耦发送者和接收者
JAVA设计模式16:职责链模式,轻松解耦发送者和接收者
|
6月前
|
设计模式 Java 应用服务中间件
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
75 0
|
Java
Java 实现汉字按照首字母分组排序
Java 实现汉字按照首字母分组排序
556 0
|
9月前
|
设计模式 Java uml
Java中23种面试常考的设计模式之责任链模式(Chain of Responsibility)---行为型模式
Java中23种面试常考的设计模式之责任链模式(Chain of Responsibility)---行为型模式
58 1
|
9月前
|
设计模式 Java API
【设计模式】用Java实现职责链模式
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理链进行传递,直到有一个处理者能够处理该请求。每个处理者都可以决定是否将请求传递给下一个处理者,从而形成一条处理链。
64 0
|
分布式计算 Java Hadoop
Java实现单词计数MapReduce
本文分享实现单词计数MapReduce的方法
301 0
|
Java 数据安全/隐私保护
JAVA 实现上传图片添加水印(详细版)(上)
JAVA 实现上传图片添加水印(详细版)
916 0
JAVA 实现上传图片添加水印(详细版)(上)
|
存储 Java
Java实现图书管理系统
本篇文章是对目前Java专栏已有内容的一个总结练习,希望各位小主们在学习完面向对象的知识后,可以阅览本篇文章后,自己也动手实现一个这样的demo来加深总结应用已经学到知识并进行巩固。
373 0
Java实现图书管理系统
|
Java Windows Spring
java实现spring boot项目启动时,重启Windows进程
java实现spring boot项目启动时,重启Windows进程
474 0
|
数据可视化 Java
Java实现拼图小游戏(1)—— JFrame的认识及界面搭建
如果要在某一个界面里面添加功能的话,都在一个类中,会显得代码难以阅读,而且修改起来也会很困难,所以我们将游戏主界面、登录界面、以及注册界面都单独编成一个类,每一个类都继承JFrame父类,并且在类中创建方法来来实现页面
456 0
Java实现拼图小游戏(1)—— JFrame的认识及界面搭建