行为类模式(一):职责链(Chain Of Responsibility)

定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

UML

优点

  1. 将请求的发送者和接收者解耦
  2. 可以简化你的对象,因为它不需要知道链的结构
  3. 通过改变链内的成员或调动他们的次序,允许你动态地新增或删除责任

缺点

  1. 并不保证请求一定会被执行,如果没有任何对象处理它的话,它可能会落到链尾端之外
  2. 可能不容观察运行时的特征,有碍于除错。

应用场景

  1. 经常被使用在窗口系统中,处理鼠标和键盘之类的事件。
  2. 当算法牵涉到一种链型运算,而且不希望处理过程中有过多的循环和条件选择语句,并
  3. 且希望比较容易的扩充文法,可以采用职责链模式。
  4. 有多个对象处理请求,到底怎么处理在运行时确定。
  5. 希望在不明确指定接收者的情况下,向多个对象中的一个提交请求。
  6. 可处理一个请求的对象集合应该被动态指定。

示例

我们来实现一个场景,请求聚餐费用时,一般是把请求提交到项目经理处,项目经理可以处理500元以下的费用,如果费用高于500元就需要部门经理审批,如果高于1000元则需要总经理审批。

而可能出现的新需求是:公司改变了规则,高于1000元的部分要先由财务审批后再交给总经理,或者是去掉了部门经理审批的环节。通过责任链就可以方便的动态修改。

Java

  1 public class Main
  2 {
  3     public static void main(String[] args)
  4     {
  5         Handler h1 = new ProjectManager();
  6         Handler h2 = new DepManager();
  7         Handler h3 = new GeneralManager();
  8         h1.setSuccessor(h2);
  9         h2.setSuccessor(h3);
 10         
 11         System.out.println(h1.handlerFeeRequest("小李", 300));
 12         System.out.println(h1.handlerFeeRequest("小张", 300));
 13 
 14         System.out.println(h1.handlerFeeRequest("小李", 800));
 15         System.out.println(h1.handlerFeeRequest("小张", 800));
 16 
 17         System.out.println(h1.handlerFeeRequest("小李", 3000));
 18         System.out.println(h1.handlerFeeRequest("小张", 3000));
 19     }
 20 
 21     /**
 22      * 责任处理对象
 23      */
 24     public static abstract class Handler
 25     {
 26         /**
 27          * 下一个处理请求的处理对象
 28          */
 29         protected Handler successor;
 30 
 31         /**
 32          * 设置下一个处理对象
 33          */
 34         public void setSuccessor(Handler successor)
 35         {
 36             this.successor = successor;
 37         }
 38 
 39         /**
 40          * 处理聚餐费用的请求
 41          */
 42         public abstract String handlerFeeRequest(String name, double fee);
 43     }
 44     
 45     public static class ProjectManager extends Handler
 46     {
 47         @Override
 48         public String handlerFeeRequest(String name, double fee)
 49         {
 50             String str = "";
 51             if(fee < 500)
 52             {
 53                 //小于500元的可以处理
 54                 if("小李".equals(name))
 55                 {
 56                     str = "项目经理同意" + name + "的聚餐费用" + fee + "元的请求";
 57                 }
 58                 else
 59                 {
 60                     str = "项目经理不同意" + name + "的聚餐费用" + fee + "元的请求";
 61                 }
 62             }
 63             else
 64             {
 65                 if(this.successor != null)
 66                 {
 67                     return this.successor.handlerFeeRequest(name, fee);
 68                 }
 69             }
 70             return str;
 71         }
 72     }
 73 
 74     public static class DepManager extends Handler
 75     {
 76         @Override
 77         public String handlerFeeRequest(String name, double fee)
 78         {
 79             String str = "";
 80             if(fee < 1000)
 81             {
 82                 //小于1000元的可以处理
 83                 if("小李".equals(name))
 84                 {
 85                     str = "部门经理同意" + name + "的聚餐费用" + fee + "元的请求";
 86                 }
 87                 else
 88                 {
 89                     str = "部门经理不同意" + name + "的聚餐费用" + fee + "元的请求";
 90                 }
 91             }
 92             else
 93             {
 94                 if(this.successor != null)
 95                 {
 96                     return this.successor.handlerFeeRequest(name, fee);
 97                 }
 98             }
 99             return str;
100         }
101     }
102 
103     public static class GeneralManager extends Handler
104     {
105         @Override
106         public String handlerFeeRequest(String name, double fee)
107         {
108             String str = "";
109             //可以处理任意金额
110             if("小李".equals(name))
111             {
112                 str = "总经理同意" + name + "的聚餐费用" + fee + "元的请求";
113             }
114             else
115             {
116                 str = "总经理不同意" + name + "的聚餐费用" + fee + "元的请求";
117             }
118             return str;
119         }
120     }
121 }
View Code
原文地址:https://www.cnblogs.com/hammerc/p/4743798.html