責任鏈模式(Chain of Responsibility Pattern):避免請求發(fā)送者與接收者耦合在一起,讓多個對象都有可能接收請求留储,將這些對象連接成一條鏈,并且沿著這條鏈傳遞請求,直到有對象處理它為止祟剔。
一限次、先來簡單的實現(xiàn)芒涡,理一下思路:
- 每個接收者應(yīng)該知道是否處理這個任務(wù)
- 每個接收者應(yīng)該持有下一個接收者,當自己不處理時卖漫,把任務(wù)向下傳遞
向上抽取出BaseReceiver
:
public abstract class BaseReceiver {
/**
* 是否處理任務(wù)
*/
private boolean isExecute;
/**
* 下一個任務(wù)接收者
*/
private BaseReceiver nextReceiver;
public BaseReceiver(boolean isExecute) {
this.isExecute = isExecute;
}
/**
* 綁定下一個任務(wù)接收者
* @param receiver
*/
public void addNextReceiver(BaseReceiver receiver) {
nextReceiver = receiver;
}
/**
* 處理任務(wù)
*/
public abstract void execute();
/**
* 任務(wù)流费尽,每個任務(wù)判斷自己是否執(zhí)行,不執(zhí)行就傳遞給下一個任務(wù)
*/
public void run() {
if (isExecute) {
execute();
}else if (nextReceiver != null) {
nextReceiver.run();
}
}
}
創(chuàng)建出三個接收者:Receiver1
羊始、Receiver3
旱幼、Receiver3
public class Receiver1 extends BaseReceiver {
public Receiver1(boolean isExecute) {
super(isExecute);
}
@Override
public void execute() {
System.out.println("Receiver1執(zhí)行了");
}
}
測試調(diào)用:
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();
}
輸出結(jié)果:
Receiver2執(zhí)行了
揍是這么簡單。
二突委、再來一種實現(xiàn)柏卤,其實還是一樣的,只是封裝了一下匀油,上面那種addNextReceiver()
感覺有點不爽缘缚,這次用一個manager管理一下。
先看完代碼再解釋敌蚜,首先還是抽取的一個接收者接口:
public interface IBaseReceiver {
/**
*
* @param condition 判斷任務(wù)是否執(zhí)行的條件
* @param receiverManager 接受者管理器桥滨,也實現(xiàn)了IBaseReceiver
*/
public void execute(String condition, IBaseReceiver receiverManager);
}
condition
就是第一種實現(xiàn)里的是否執(zhí)行的條件,這里用一個String表示钝侠。
然后是Receiver1
该园、Receiver3
、Receiver3
public class Receiver1 implements IBaseReceiver {
@Override
public void execute(String condition, IBaseReceiver receiverManager) {
if (condition == "1") {
System.out.println("Receiver1執(zhí)行了任務(wù)");
}else {
receiverManager.execute(condition, receiverManager);
}
}
}
這里是否處理的條件帅韧,就是判斷String的值里初,具體業(yè)務(wù)中這里的判斷條件靈活修改。
看到上面一直在傳遞一個也實現(xiàn)了IBaseReceiver
的receiverManager
忽舟,肯定是不理解為什么双妨,這里看一下這個manager的實現(xiàn):
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;
/**
* 每次調(diào)用一次就會進行index++操作,用這種方式實現(xiàn)了接收者的向下傳遞
* @param condition 判斷任務(wù)是否執(zhí)行的條件
* @param receiverManager 接受者管理器叮阅,也實現(xiàn)了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);
}
}
看完調(diào)用再解釋上面的函數(shù)刁品,調(diào)用:
ReceiverManager receiverManager = new ReceiverManager();
receiverManager.addReceiver(new Receiver1());
receiverManager.addReceiver(new Receiver2());
receiverManager.addReceiver(new Receiver3());
receiverManager.execute("2", receiverManager);
運行結(jié)果:
Receiver2執(zhí)行了任務(wù)
理一下上面的流程,這里的調(diào)用有點繞浩姥,但是很巧妙:
調(diào)用的時候receiverManage
r執(zhí)行execute()
時挑随,參數(shù)直接傳入了他自己,那直接進入到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
的一個實例,執(zhí)行Receiver1
的execute()
拌汇,并且還是把這個receiverManager
傳遞了過去柒桑,注意在這之前進行了index++
,也就是傳遞過去的這個receiverManager
中的index
已經(jīng)等于1了噪舀。
然后來到Receiver1
中:
public class Receiver1 implements IBaseReceiver {
@Override
public void execute(String condition, IBaseReceiver receiverManager) {
if (condition == "1") {
System.out.println("Receiver1執(zhí)行了任務(wù)");
}else {
receiverManager.execute(condition, receiverManager);
}
}
}
因為傳遞過來的condition
為2魁淳,不滿足執(zhí)行條件,所以走了else的流程与倡,用傳遞過來的receiverManager
繼續(xù)執(zhí)行execute()
界逛,還是要注意,這個receiverManager
中的index已經(jīng)是等于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
直接處理了任務(wù)扰付,不再繼續(xù)進行,如果條件還是不滿足仁讨,繼續(xù)Receiver3
羽莺,這么一直循環(huán)下去。
還是亂的話洞豁,跟著代碼理一下盐固,其實很簡單很清晰,也有點妙丈挟。
這種設(shè)計模式的使用也很常見刁卜,Android源碼中的事件傳遞,Okhttp中的攔截器曙咽,好多好多蛔趴,都是使用到。