设计模式读书笔记之职责链模式(chain of responsibility)

职责链模式:当一个请求有可能被多个对象处理,则将这些对象连成一条链,并沿着这条链传递请求,直到该请求被处理为止。

单看上图, 你肯定看不出职责链模式的特征, 先举一个例子来说明一下. 比如一个员工想加工资, 他首先会告知team leader, 如果在team leader授权范围之内,则他可以办到, 否则,就要请求上级来处理,最后直到老板, 于是很容易写出这样的代码来:

[java]  view plain  copy
  1. public class Employee {  
  2.     private TeamLeader tl;  
  3.     private DeptManager deptMgr;  
  4.     private GeneralManager gm;  
  5.     private Boss boss;  
  6.     //some other properties  
  7.     public void addSalary(int x){  
  8.         if(x<=100){  
  9.             tl.addSalary(this, x);  
  10.         }  
  11.         else if(x<=500){  
  12.             deptMgr.addSalary(this, x);  
  13.         }  
  14.         else if(x<=800){  
  15.             gm.addSalary(this, x);  
  16.         }  
  17.         else{  
  18.             boss.addSalary(this, x);  
  19.         }  
  20.     }  
  21.     // some other methods  
  22. }  

这个代码中的if else带来了坏味道, 同时, Employee必须知道他的每一个上司,并使Employee和每一个处理者(他的上司)耦合在一起. 其实一个Employee一般来说只需要和他的直接上司打交道就可以了. 就如下时序图所示.

把Employee的上司连成一条链, 即team leader持有他的上司部门经理, 部门经理持有他的上司总经理, 总经理持有他的上司老板. 则Employee只需要知道team leader即可.

加薪代码:

[java]  view plain  copy
  1. //  
  2. public interface Supervisor {  
  3.     public void addSalary(Employee e, int added);  
  4. }  
  5.   
  6. ///  
  7. public class Employee {  
  8.     public String name;  
  9.     private Supervisor supervisor;  
  10.     public Employee(String name){  
  11.         this.name = name;  
  12.     }  
  13.     public void setSupervisor(Supervisor supervisor) {  
  14.         this.supervisor = supervisor;  
  15.     }  
  16.     public void addSalary(int added){  
  17.         if(supervisor!=null){  
  18.             supervisor.addSalary(this, added);  
  19.         }  
  20.     }  
  21.       
  22. }  
  23. ///  
  24. public class TeamLeader implements Supervisor{  
  25.     private Supervisor successor;  
  26.     public TeamLeader(Supervisor s){  
  27.         this.successor = s;  
  28.     }  
  29.     public void addSalary(Employee e, int added) {  
  30.         if(added<100){  
  31.             System.out.println("Team Leader: " + e.name + " want to add "   
  32.                     + added + " salary, I can process it, done!");  
  33.         }  
  34.         else if(successor!=null){  
  35.             System.out.println("Team Leader: " + e.name + " want to add "   
  36.                     + added + " salary, I can't process it, but my supervisor can do!");  
  37.             successor.addSalary(e, added);  
  38.         }  
  39.     }  
  40. }  
  41. ///  
  42. public class DeptManager implements Supervisor{  
  43.     private Supervisor successor;  
  44.     public DeptManager(Supervisor s){  
  45.         this.successor = s;  
  46.     }  
  47.     public void addSalary(Employee e, int added) {  
  48.         if(added<500){  
  49.             System.out.println("Dept Manager: " + e.name + " want to add "   
  50.                     + added + " salary, I can process it, done!");  
  51.         }  
  52.         else if(successor!=null){  
  53.             System.out.println("Dept Manager: " + e.name + " want to add "   
  54.                     + added + " salary, I can't process it, but my supervisor can do!");  
  55.             successor.addSalary(e, added);  
  56.         }  
  57.     }  
  58. }  
  59. ///  
  60. public class GeneralManager implements Supervisor{  
  61.     private Supervisor successor;  
  62.     public GeneralManager(Supervisor s){  
  63.         this.successor = s;  
  64.     }  
  65.     public void addSalary(Employee e, int added) {  
  66.         if(added<800){  
  67.             System.out.println("General Manager: " + e.name + " want to add "   
  68.                     + added + " salary, I can process it, done!");  
  69.         }  
  70.         else if(successor!=null){  
  71.             System.out.println("General Manager: " + e.name + " want to add "   
  72.                     + added + " salary, I can't process it, but my supervisor can do!");  
  73.             successor.addSalary(e, added);  
  74.         }  
  75.     }  
  76. }  
  77. //  
  78. public class Boss implements Supervisor{  
  79.     public Boss(){}  
  80.     public void addSalary(Employee e, int added) {  
  81.         //boss具有最终处理权限, 但是他打官腔  
  82.         System.out.println("Boss: I will process it soon.");  
  83.     }  
  84. }  
  85. /  
  86. //测试用例  
  87. public class Test {  
  88.     public static void main(String[] args) {  
  89.         Employee e = new Employee("Jack");  
  90.         Boss b = new Boss();  
  91.         GeneralManager gm = new GeneralManager(b);  
  92.         DeptManager dm = new DeptManager(gm);  
  93.         TeamLeader tl = new TeamLeader(dm);  
  94.         e.setSupervisor(tl);  
  95.         e.addSalary(1200);  
  96.     }  
  97. }  
  98. /  
  99. //输出  
  100. //Team Leader: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
  101. //Dept Manager: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
  102. //General Manager: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
  103. //Boss: I will process it soon.  

上面的代码有两个优点:

1 Employee不再依赖于具体的上司,转而依赖于抽象, 而且不必知道所有的上司;

2 如果新增了处理者, 只需要更改客户端代码, 即重新构造责任链就可以了.

 

基础代码:

[java]  view plain  copy
  1. package designpattern.chainofresponsibility;  
  2.   
  3. public abstract class Handler {  
  4.     //注意修饰符为protected,因为子类要访问他  
  5.     protected Handler successor;  
  6.       
  7.     public void setSuccessor(Handler successor) {  
  8.         this.successor = successor;  
  9.     }  
  10.       
  11.     public abstract void handleRequest(int request);  
  12. }  
  13. //  
  14. package designpattern.chainofresponsibility;  
  15.   
  16. public class ConcreteHandler1 extends Handler {  
  17.     public void handleRequest(int request) {  
  18.         if(request>=0&&request<10){  
  19.             System.out.println("request handled by ConcreteHandler1");  
  20.             return;  
  21.         }  
  22.         if(successor!=null){  
  23.             System.out.println("ConcreteHandler1 can't handle this request, dispatch to next.");  
  24.             successor.handleRequest(request);  
  25.         }  
  26.     }  
  27. }  
  28. //  
  29. package designpattern.chainofresponsibility;  
  30.   
  31. public class ConcreteHandler2 extends Handler {  
  32.     public void handleRequest(int request) {  
  33.         if(request>=10&&request<20){  
  34.             System.out.println("request handled by ConcreteHandler2");  
  35.             return;  
  36.         }  
  37.         if(successor!=null){  
  38.             System.out.println("ConcreteHandler2 can't handle this request, dispatch to next.");  
  39.             successor.handleRequest(request);  
  40.         }  
  41.     }  
  42. }  
  43. //  
  44. package designpattern.chainofresponsibility;  
  45.   
  46. public class ConcreteHandler3 extends Handler {  
  47.     public void handleRequest(int request) {  
  48.         if(request>=20&&request<30){  
  49.             System.out.println("request handled by ConcreteHandler3");  
  50.             return;  
  51.         }  
  52.         if(successor!=null){  
  53.             System.out.println("ConcreteHandler3 can't handle this request, dispatch to next.");  
  54.             successor.handleRequest(request);  
  55.         }  
  56.     }  
  57. }  
  58. //  
  59. package designpattern.chainofresponsibility;  
  60.   
  61. public class ConcreteHandler4 extends Handler {  
  62.     public void handleRequest(int request) {  
  63.         if(request>=30){  
  64.             System.out.println("request handled by ConcreteHandler3");  
  65.             return;  
  66.         }  
  67.     }  
  68. }  
  69. //客户端测试用例  
  70. package designpattern.chainofresponsibility;  
  71.   
  72. public class Client {  
  73.     public static void main(String[] args){  
  74.         Handler handler1 = new ConcreteHandler1();  
  75.         Handler handler2 = new ConcreteHandler2();  
  76.         Handler handler3 = new ConcreteHandler3();  
  77.         Handler handler4 = new ConcreteHandler4();  
  78.         handler1.setSuccessor(handler2);  
  79.         handler2.setSuccessor(handler3);  
  80.         handler3.setSuccessor(handler4);  
  81.         handler1.handleRequest(60);  
  82.     }  
  83. }  

责任链模式的关键点在于把请求的处理者连成一条链,一个处理者可以处理当前请求,也有权决定是否沿着链朝上传递请求.

优点:

1 可以简化对象之间的连接,他们只需要知道一个后继者就行了;

2 可以很方便的增加或修改处理者。

 

注意:

一个请求可以传递到末端都得不到处理,因此需要考虑全面。

 

经典案例:

jdk中我真的没有找到合适的例子,网上说Java 1.0版本中的AWT库采用责任链模式和命令模式来处理GUI的事件,我觉得有兴趣你可以看一下源码.DHTML中的事件处理机制可以看作职责链模式,这种机制又叫事件冒泡(Event Bubbling)机制, 当页面中的一个dom节点捕获一个事件(比如鼠标双击), 当前节点的处理函数可以处理改事件,然后也可以决定是否向上冒泡让父元素继续处理这个事件.浏览器的事件处理机制也是这样的。

如果你想到了j2ee中的Filter,或者spring中的Interceptor和ExecutionChain, 那你就错了. 因为就实现方法上看, Filter和Interceptor以及ExecutionChain都不是职责链模式.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值