責任鏈模式(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中的攔截器,好多好多,都是使用到。