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

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

适用场景:性能

一、有多个的对象能够处理一个请求,哪一个对象处理该请求运行时刻自动肯定;测试

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

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

通用类图:代理

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

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

类图结构以下:递归

 代码实现以下:接口

  
  
           
  
  
  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个点:
一、处理者在运行时动态肯定实际上是咱们在 Client 中组装的链所引发的,由于具体的职责逻辑就在链中一一对应起来;
二、由于不肯定请求的具体处理者是谁,因此咱们把全部可能的处理者组装成一条链,在遍历的过程当中就至关于向每一个处理者都提交了这个请求,等待其审查。而且在审查过程当中,即便不是最终处理者,也能够进行一些请求的“包装”操做(这种功能相似于装饰者模式),例如上面例子中的签名批准;
三、处理者集合的动态指定跟上面的第一、2点相似,即在 Client 类中建立了全部可能的处理者。
 
不足之处:

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

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

 我的见解:

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

相关文章:

命令模式(Command)的两种不一样实现(http://haolloyin.blog.51cto.com/1177454/339076

(Template Method)模板方法模式的Java实现(http://haolloyin.blog.51cto.com/1177454/333063

装饰模式(Decorator)与动态代理的强强联合(http://haolloyin.blog.51cto.com/1177454/338671

相关文章
相关标签/搜索