通过理论,代码示例,Android源码来学习责任链模式
介绍
责任链模式 (Iterator Pattern) ,属于行为型设计模式之一。什么是 “链” ?我们将多个节点首尾相连所构成的模型称为链
。就好比生活中一个个铁圆环一个连这一个环环相扣一样。
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到处理为止。
使用场景
- 多个对象可以处理同一个请求,但是具体由哪个对象处理则在运行时动态决定。
- 在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
- 需要动态指定一组对象处理请求。
UML 类图
- Handler : 抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点 Handler 的引用。
- ConcreteHandler: 具体处理角色,对请求进行处理,如果不能处理则将该请求转发给下一个请求。
实战
简单示例1:
定义抽象处理者:
1 | public abstract class Handler { |
定义抽象请求者:
1 | public abstract class HandlerRequest { |
定义具体处理者:
1 | public class HandlerA extends Handler { |
1 | public class HandlerB extends Handler { |
定义具体请求者:
1 | public class RequestA extends HandlerRequest { |
1 | public class RequestB extends HandlerRequest { |
定义 Client 测试:
1 | /** |
Output:
1 | handlerRequest = [HandlerA A] |
从测试代码可以看到 ,我们的 handlerA 的下一个请求交给了 handlerB,那么在发起请求的时候内部就会判断,如果当前发起请求的级别跟处理事件的级别不符合的话 ,就交给下一个节点来判断,如果都没有找到就报空。
实战示例2:
在 Android 中我们知道 Broadcast 可以分为 2 种,一种是普通广播,一种是有序广播,普通广播是异步的,发出时可以被所有的接收者收到;而有序广播则是根据优先级依次传播的,直到接收者将其处理,是不是觉得有序广播跟我们的责任链模式很相似,通过广播也能达到实现责任链事件的处理,下面先看代码:
先动态注册 3 个广播
1 | private void registerOrderBroadcast() { |
1 | public class ReceiverA extends BroadcastReceiver { |
…其它 2 个广播省略 内部代码只有 limit == ? 不一样
发送一个有序广播:
1 | public void order(View view) { |
Output:
1 | 2019-09-08 13:40:41.551 28992-28992/com.devyk.android_dp_code I/ReceiverA: 我不处理,分发下去 |
这里我们动态注册了 3 个广播,优先级越高越先收到 A,B 都不符合要求,所以下发下去,最后在 C 接收者里面处理。
总结
优点:
可以对请求者和处理者关系解耦,提高代码灵活性。
缺点:
对链中请求处理者的遍历,如果处理者太多,那么遍历会影响一定的性能,特别是在一些递归调用中,要慎用。
但总体来说,优点是大于缺点的,缺点相对于优点来说还是可控的。