1、介绍
多个节点首尾相连多构成的模型称为链。将这种结构应用到编程领域,将每个节点看作是一个对象,将一个请求对链式的首端发出,沿着链的路径传递给每一个节点对象,直到有对象处理了该请求为止,这种模式称为责任链模式。
2、定义
使得对个对象有机会处理请求,从而避免了请求的发送者和接收者之间的耦合性关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
3、使用场景
- 一个请求需要一系列的处理工作
- 业务流的处理,例如:文件审批
- 多个对象可以处理同一请求,但需运行时动态决定哪个对象处理该请求
4、UML类图
角色说明:
- Handler:抽象处理者对象,声明了处理处理请求的方法,并保持 下一个处理者的引用
- ConcreteHandler:具体的处理者对象,处理请求,不能处理则传递给下一一下处理者进行处理
5、示例
小明出差深圳一个月回来需要报销费用5万,小明的直接向组长申请报销费用,由于组长的权限是1000,所以组长拿着报销单得向主管申请,但是主管的权限是5000,于是主管又去找经理,但是经理的最高审批额度是1w,经理又去找大boss进行审批,小明只需将报销单给组长,无需关心谁最终审批,责任链模式很好地将请求者和处理者进行解耦。具体代码如下:
/** * 抽象处理者 */ public abstract class Leader { protected Leader nextHandler; /** * 处理报账请求 * @param money */ public void handleRequest(int money){ if (money <= limit()){ handle(money); } else { if (nextHandler != null) { nextHandler.handleRequest(money); } } } /** * 返回自身能够审批的额度 * @return */ public abstract int limit(); /** * 处理报账行为 * @param money 具体金额 */ public abstract void handle(int money); }
/** * 具体的处理者 */ public class GroupLeader extends Leader { @Override public int limit() { return 1000; } @Override public void handle(int money) { System.out.println("组长批复报销:" + money + "元"); } }
/** * 具体的处理者 */ public class Director extends Leader { @Override public int limit() { // TODO Auto-generated method stub return 5000; } @Override public void handle(int money) { System.out.println("主管批复报销:" + money + "元"); } }
/** * 具体的处理者 */ public class Manager extends Leader { @Override public int limit() { // TODO Auto-generated method stub return 10000; } @Override public void handle(int money) { System.out.println("经理批复报销:" + money + "元"); } }
/** * 具体的处理者 */ public class Boss extends Leader { @Override public int limit() { return Integer.MAX_VALUE; } @Override public void handle(int money) { System.out.println("老板批复报销:" + money + "元"); } }
/** * 客户端模拟小明的报销流程 */ public class Client { public static void main(String[] args) { // 构造各个领导者 GroupLeader groupLeader = new GroupLeader(); Director director = new Director(); Manager manager = new Manager(); Boss boss = new Boss(); // 构造链,这个每一个处理者的下个处理对象 groupLeader.nextHandler = director; director.nextHandler = manager; manager.nextHandler = boss; // 发起报销流程 groupLeader.handleRequest(50000); } }
输出结果如下:
老板批复报销:50000元
6、总结
优点:请求者和处理者解耦,提高了代码的灵活性
缺点:
- 降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长时,性能下降
- 不易于调试,由于采用了类似递归的方式,调试逻辑较为复杂
文章来源: 行为型(三)― 责任链模式