责任链模式(Chain of Responsibility Pa
责任链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
一、先来简单的实现,理一下思路:
- 每个接收者应该知道是否处理这个任务
- 每个接收者应该持有下一个接收者,当自己不处理时,把任务向下传递
向上抽取出BaseReceiver
:
public abstract class BaseReceiver {
/**
* 是否处理任务
*/
private boolean isExecute;
/**
* 下一个任务接收者
*/
private BaseReceiver nextReceiver;
public BaseReceiver(boolean isExecute) {
this.isExecute = isExecute;
}
/**
* 绑定下一个任务接收者
* @param receiver
*/
public void addNextReceiver(BaseReceiver receiver) {
nextReceiver = receiver;
}
/**
* 处理任务
*/
public abstract void execute();
/**
* 任务流,每个任务判断自己是否执行,不执行就传递给下一个任务
*/
public void run() {
if (isExecute) {
execute();
}else if (nextReceiver != null) {
nextReceiver.run();
}
}
}
创建出三个接收者:Receiver1
、Receiver3
、Receiver3
public class Receiver1 extends BaseReceiver {
public Receiver1(boolean isExecute) {
super(isExecute);
}
@Override
public void execute() {
System.out.println("Receiver1执行了");
}
}
测试调用:
public static void main(String[] args) {
Receiver1 receiver1 = new Receiver1(false);
Receiver2 receiver2 = new Receiver2(true);
Receiver3 receiver3 = new Receiver3(false);
receiver1.addNextReceiver(receiver2);
receiver2.addNextReceiver(receiver3);
receiver1.run();
}
输出结果:
Receiver2执行了
揍是这么简单。
二、再来一种实现,其实还是一样的,只是封装了一下,上面那种addNextReceiver()
感觉有点不爽,这次用一个manager管理一下。
先看完代码再解释,首先还是抽取的一个接收者接口:
public interface IBaseReceiver {
/**
*
* @param condition 判断任务是否执行的条件
* @param receiverManager 接受者管理器,也实现了IBaseReceiver
*/
public void execute(String condition, IBaseReceiver receiverManager);
}
condition
就是第一种实现里的是否执行的条件,这里用一个String表示。
然后是Receiver1
、Receiver3
、Receiver3
public class Receiver1 implements IBaseReceiver {
@Override
public void execute(String condition, IBaseReceiver receiverManager) {
if (condition == "1") {
System.out.println("Receiver1执行了任务");
}else {
receiverManager.execute(condition, receiverManager);
}
}
}
这里是否处理的条件,就是判断String的值,具体业务中这里的判断条件灵活修改。
看到上面一直在传递一个也实现了IBaseReceiver
的receiverManager
,肯定是不理解为什么,这里看一下这个manager的实现:
public class ReceiverManager implements IBaseReceiver {
/**
* 接收者集合
*/
private List<IBaseReceiver> receivers = new ArrayList<>();
/**
* 添加接收者
* @param receiver
*/
public void addReceiver(IBaseReceiver receiver) {
receivers.add(receiver);
}
/**
* 当前接收者角标
*/
private int index = 0;
/**
* 每次调用一次就会进行index++操作,用这种方式实现了接收者的向下传递
* @param condition 判断任务是否执行的条件
* @param receiverManager 接受者管理器,也实现了IBaseReceiver
*/
@Override
public void execute(String condition, IBaseReceiver receiverManager) {
if (receivers.isEmpty()) return;
if (index >= receivers.size()) return;
IBaseReceiver receiver = receivers.get(index);
index++;
receiver.execute(condition, receiverManager);
}
}
看完调用再解释上面的函数,调用:
ReceiverManager receiverManager = new ReceiverManager();
receiverManager.addReceiver(new Receiver1());
receiverManager.addReceiver(new Receiver2());
receiverManager.addReceiver(new Receiver3());
receiverManager.execute("2", receiverManager);
运行结果:
Receiver2执行了任务
理一下上面的流程,这里的调用有点绕,但是很巧妙:
调用的时候receiverManage
r执行execute()
时,参数直接传入了他自己,那直接进入到ReceiverManager
的execute ()
方法:
public void execute(String condition, IBaseReceiver receiverManager) {
...
//此时index为0,receiver为Receiver1的实例对象
IBaseReceiver receiver = receivers.get(index);
index++;
receiver.execute(condition, receiverManager);
}
index的初始值是0,那直接拿到集合中的第一个元素,也就是Receiver1
的一个实例,执行Receiver1
的execute()
,并且还是把这个receiverManager
传递了过去,注意在这之前进行了index++
,也就是传递过去的这个receiverManager
中的index
已经等于1了。
然后来到Receiver1
中:
public class Receiver1 implements IBaseReceiver {
@Override
public void execute(String condition, IBaseReceiver receiverManager) {
if (condition == "1") {
System.out.println("Receiver1执行了任务");
}else {
receiverManager.execute(condition, receiverManager);
}
}
}
因为传递过来的condition
为2,不满足执行条件,所以走了else的流程,用传递过来的receiverManager
继续执行execute()
,还是要注意,这个receiverManager
中的index已经是等于1的,那么就又回到了ReceiverManager
的代码中:
public void execute(String condition, IBaseReceiver receiverManager) {
...
//此时index为1,receiver为Receiver2的实例对象
IBaseReceiver receiver = receivers.get(index);
index++;
receiver.execute(condition, receiverManager);
}
因为receiverManager
一直是同一个对象,只是传递来传递去,没有new,所以这里的index为1,拿到的receiver为Receiver2的实例对象,那么就进入了Receiver2
的execute()
,这里逻辑就不再贴了,跟进入Receiver1
的是一样的,只是判断条件不同,因为条件满足,Receiver2
直接处理了任务,不再继续进行,如果条件还是不满足,继续Receiver3
,这么一直循环下去。
还是乱的话,跟着代码理一下,其实很简单很清晰,也有点妙。
这种设计模式的使用也很常见,Android源码中的事件传递,Okhttp中的拦截器,好多好多,都是使用到。