1、介绍
多个节点首尾相连多构成的模型称为链。将这种结构应用到编程领域,将每个节点看作是一个对象,将一个请求对链式的首端发出,沿着链的路径传递给每一个节点对象,直到有对象处理了该请求为止,这种模式称为责任链模式。
2、定义
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
使得对个对象有机会处理请求,从而避免了请求的发送者和接收者之间的耦合性关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
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、总结
优点:请求者和处理者解耦,提高了代码的灵活性
缺点:
- 降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长时,性能下降
- 不易于调试,由于采用了类似递归的方式,调试逻辑较为复杂