概述
责任链模式是行为型模式,该模式中包含了一些命令对象和一系列的处理对象,每一个对象都都保有对其下家的引用.如果我们将链中的每个节点看做是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链的首端发出,依次传到下一个节点处理.直到链上链上的某一个对象决定处理此请求,客户端并不需要知道那个对象处理的.
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,将这些对象链接成一条链,并沿着这条链传递该请求,直到有对象处理它为止
使用场景
- 多个对象可以处理统一请求,但具体由哪个对象处理则在运行时动态决定/
- 在请求处理者不明确的情况系向多个对象中的一个提交一个请求.
- 需要动态指定一组对象处理请求
UML类图
其中涉及到的角色有:
Handler
: 抽象处理者角色,声明一个请求处理的方法,并保持下一个处理节点Handler
对象的引用.ConcreteHandler
: 具体处理者角色,对请求进行处理,如果不能处理,则将请求传递给下一个节点Handler
实例
责任链有点像古时候的击鼓传花,鼓声落时,花在谁手里,谁执行喝酒的命令.比如在公司中,不停的领导有不同的授权报销费用,
这就是一个简单的职责链了.下面用责任链模式来模拟一下报销流程.
- 抽象处理者
public abstract class Leader {
protected Leader nextHandler;
public final void handleRequest(int money) {
if (money < limit()) {
//如果权限够,就处理
handle(money);
} else {
if (null != nextHandler) {
//否则,让下一个处理者处理
nextHandler.handleRequest(money);
}
}
}
public abstract int limit();
public abstract void handle(int money);
}
- 具体处理者
// 组长,主管,经理和Boss 的授权 额度是不同的
public class GroupLeader extends Leader {
private static final String TAG = "GroupLeader";
@Override public int limit() {
return 1000;
}
@Override public void handle(int money) {
Log.d(TAG, "handle: 组长批复报销--->" + money + "元");
}
}
//....
public class Boss extends Leader {
private static final String TAG = "Boss";
@Override public int limit() {
return Integer.MAX_VALUE;
}
@Override public void handle(int money) {
Log.d(TAG, "handle: 老板批复报销--->"+ money + "元");
}
}
- 客户端类
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;
//发出 50000 的申请
groupLeader.handleRequest(50000);
在这里并不一定要一级级的申请,比如我们可以不从组长开始,直接找老板报批.
答案是肯定的,这就是责任链模式的灵活之处.
在责任链模式中如需我们从任意节点开始发起请求
而且可以改变内部传递规则,比如主管不在,可以直接跨过,找经理
责任链节点只有两个行为,处理请求和将请求传递给下一个节点
对于一个请求最终只有两种结果,一是被处理,一是所有对象均未处理
责任链模式的优缺点
责任链中的有点十分明显,也存在着一定的缺点
优点是,可以对请求者和处理者关系解耦,提高灵活性
缺点当链中的对象过多时,遍历必定会影响性能,而且中间传递者如果没有处理的话,就会产生很多内存垃圾对象.