前言
责任链模式(Iterator Pattern),是行为型设计模式之一。什么是“链”?我们将多个节点首尾相连所构成的模型称为链,比如生活中常见的锁链,就是由一个个圆角长方形的铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式。在Android中责任链的实现莫过于对事件的分发处理。
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景
- 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
- 在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
简单案例
小民某天接到通知说需要出差去外地进修学习新技术,小民听到这消息心中一喜,于是收拾完背包后踏上了去外地进修的旅途。去外地学习一趟花费了近5万元,于是小民上班后的第一天就向组长申请报销费用,组长一看是笔不小的数目,他没有权限审批,于是组长就拿着票据去找部门主管,主管一看要报这么多钱,自己权限内只能批五千以下的费用,这完全超出了自己的权限范围,于是主管又跑去找经理,经理一看二话不说直接拿着票据奔向了老板的办公室,因为他也只能批一万以下的费用。类似的情况对上班族来说肯定并不少见,上面的这个情景其实就是一个责任链的小例子,每一个人,准确地说是每一类人代表这条链上的一个节点,小民是请求的发起者,而老板则是处于链条顶端的类,小民从链的底端开始发出一个申请报账的请求,首先由组长处理该请求,组长比对后发现自己权限不够于是将该请求转发给位于链中下一个节点的主管,主管比对后也发现自己权限不够又将该请求转发给经理,而经理也基于同样的原因将请求转发给老板,这样层层转达直至请求被处理,从中大家可以看到一个显而易见的事,就是至始至终小民只与组长产生了关联,后面具体由谁处理的票据,小民并不关心,唯一在乎的是报账的结果,责任链模式在这里很好地将请求的发起者与处理者解耦。
- 声明一个抽象的领导类。
public abstract class Leader {
//上一级领导处理者
public Leader nextHandler;
/**
* 处理报账请求
*
* @param money 能批复的报账额度
*/
public final void handleRequest(int money) {
if (money <= limit()) {
handle(money);
} else {
if (null != nextHandler)
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() {
return 5000;
}
@Override
public void handle(int money) {
System.out.println("主管批复报销" + money + "元");
}
}
public class Manager extends Leader{
@Override
public int limit() {
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 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);
}
总结
世界不是完美的,所以不会有完美的事物存在。就像所有的设计模式一样,有优点也有缺点,但总体来说优点必定大于缺点或者说缺点相对于优点来说更可控。责任链模式也一样,优点显而易见,可以对请求者和处理者关系解耦,提高代码的灵活性。责任链模式的最大缺点是对链中请求处理者的遍历,如果处理者太多那么遍历必定会影响性能,特别是在一些递归调用中,要慎重。