1. 职责链模式的概念
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这个条链传递该请求,直到有一个对象处理它为止。
在Java/Android开发中,这个模式我们并不陌生,比如Java的类加载机制,“双亲委托”模型,Android中触摸事件的传递机制,都体现了职责链模式。
以上面的模型来理解责任链模式,对于一个事件来说,它并不需要知道谁来处理它,这样就解除了事件和处理事件的对象的耦合。
2. UML图

来看看样板代码。
首先是
Handler
类,它是处理者类的基类,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。
public abstract class Handler {
protected Handler successor; //下一节点的处理者
/**
* 处理请求
*/
public abstract void handleRequest(String condition);
}
接着是具体的处理者
ConcreteHandler
,对请求进行处理,如果不能处理则将该请求转发给下一个Handler对象的引用。
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(String condition) {
if (condition.equals("ConcreteHandler1")) {
System.out.println("ConcreteHandler1 handler");
} else {
successor.handleRequest(condition);
}
}
}
最后是客户端类:
public static void main(String[] args){
// 构造一个ConcreteHandlerA对象
ConcreteHandlerA handlerA = new ConcreteHandlerA();
// 构造一个ConcreteHandlerB对象
ConcreteHandlerB handlerB = new ConcreteHandlerB();
// 设置handlerA的下一个节点
handlerA.successor = handlerB;
// 设置handlerB的下一个节点
handlerB.successor = handlerA;
// 处理请求
handlerA.handleRequest("ConcreteHandler2");
}
3. 责任链模式在Android中的实现
Android Framework层的触摸事件的分发机制,就是责任链模式在Android中的体现。
可以我之前总结的这篇:源码分析View的事件分发
如果我们要在Android的代码中实现责任链模式,一个很好的应用就是“有序广播”,通过它我们可以轻松的实现全局的责任链事件的处理。
下面我们实现一个接受广播的广播接收器:
public class FirstReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取Intent中附加的限制值
int limit = intent.getIntExtra("limit", -1001);
//如果限制值等于1000, 则处理, 否则继续转发给下一个Receive
if (limit == 1000) {
Log.d("iterator pattern", "FirstReceiver 接收");
//终止广播
abortBroadcast();
} else {
//添加信息发送给下一个Receiver
Bundle b = new Bundle();
b.putString("new", "Message from FirstReceiver");
setResultExtras(b);
}
}
}
之后的广播接收器和这个差不多,他们只要处理自己能处理的限制值,就会通过
abortBroadcast()
来终止广播。
4. 小结
责任链的使用场景:多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
- 处理者和请求者在关系上解耦。
- 我们可以随时地增加或则修改处理一个请求的结构,这提高了代码的灵活性。
- 责任链模式最大的缺点就是对链中请求处理者的遍历,如果处理者太多,那么遍历必定会影响性能,特别是在一些递归调用中,要慎重使用。