責(zé)任鏈模式(Chain of Responsibility Pattern):避免請(qǐng)求發(fā)送者與接收者耦合在一起,讓多個(gè)對(duì)象都有可能接收請(qǐng)求,將這些對(duì)象連接成一條鏈,并且沿著這條鏈傳遞請(qǐng)求,直到有對(duì)象處理它為止。
一、先來(lái)簡(jiǎn)單的實(shí)現(xiàn),理一下思路:
- 每個(gè)接收者應(yīng)該知道是否處理這個(gè)任務(wù)
- 每個(gè)接收者應(yīng)該持有下一個(gè)接收者,當(dāng)自己不處理時(shí),把任務(wù)向下傳遞
向上抽取出BaseReceiver:
public abstract class BaseReceiver {
/**
* 是否處理任務(wù)
*/
private boolean isExecute;
/**
* 下一個(gè)任務(wù)接收者
*/
private BaseReceiver nextReceiver;
public BaseReceiver(boolean isExecute) {
this.isExecute = isExecute;
}
/**
* 綁定下一個(gè)任務(wù)接收者
* @param receiver
*/
public void addNextReceiver(BaseReceiver receiver) {
nextReceiver = receiver;
}
/**
* 處理任務(wù)
*/
public abstract void execute();
/**
* 任務(wù)流,每個(gè)任務(wù)判斷自己是否執(zhí)行,不執(zhí)行就傳遞給下一個(gè)任務(wù)
*/
public void run() {
if (isExecute) {
execute();
}else if (nextReceiver != null) {
nextReceiver.run();
}
}
}
創(chuàng)建出三個(gè)接收者:Receiver1、Receiver3、Receiver3
public class Receiver1 extends BaseReceiver {
public Receiver1(boolean isExecute) {
super(isExecute);
}
@Override
public void execute() {
System.out.println("Receiver1執(zhí)行了");
}
}
測(cè)試調(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í)行了
揍是這么簡(jiǎn)單。
二、再來(lái)一種實(shí)現(xiàn),其實(shí)還是一樣的,只是封裝了一下,上面那種addNextReceiver()感覺(jué)有點(diǎn)不爽,這次用一個(gè)manager管理一下。
先看完代碼再解釋,首先還是抽取的一個(gè)接收者接口:
public interface IBaseReceiver {
/**
*
* @param condition 判斷任務(wù)是否執(zhí)行的條件
* @param receiverManager 接受者管理器,也實(shí)現(xiàn)了IBaseReceiver
*/
public void execute(String condition, IBaseReceiver receiverManager);
}
condition就是第一種實(shí)現(xiàn)里的是否執(zhí)行的條件,這里用一個(gè)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ù)中這里的判斷條件靈活修改。
看到上面一直在傳遞一個(gè)也實(shí)現(xiàn)了IBaseReceiver的receiverManager,肯定是不理解為什么,這里看一下這個(gè)manager的實(shí)現(xiàn):
public class ReceiverManager implements IBaseReceiver {
/**
* 接收者集合
*/
private List<IBaseReceiver> receivers = new ArrayList<>();
/**
* 添加接收者
* @param receiver
*/
public void addReceiver(IBaseReceiver receiver) {
receivers.add(receiver);
}
/**
* 當(dāng)前接收者角標(biāo)
*/
private int index = 0;
/**
* 每次調(diào)用一次就會(huì)進(jìn)行index++操作,用這種方式實(shí)現(xiàn)了接收者的向下傳遞
* @param condition 判斷任務(wù)是否執(zhí)行的條件
* @param receiverManager 接受者管理器,也實(shí)現(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);
運(yùn)行結(jié)果:
Receiver2執(zhí)行了任務(wù)
理一下上面的流程,這里的調(diào)用有點(diǎn)繞,但是很巧妙:
調(diào)用的時(shí)候receiverManager執(zhí)行execute()時(shí),參數(shù)直接傳入了他自己,那直接進(jìn)入到ReceiverManager的execute ()方法:
public void execute(String condition, IBaseReceiver receiverManager) {
...
//此時(shí)index為0,receiver為Receiver1的實(shí)例對(duì)象
IBaseReceiver receiver = receivers.get(index);
index++;
receiver.execute(condition, receiverManager);
}
index的初始值是0,那直接拿到集合中的第一個(gè)元素,也就是Receiver1的一個(gè)實(shí)例,執(zhí)行Receiver1的execute(),并且還是把這個(gè)receiverManager傳遞了過(guò)去,注意在這之前進(jìn)行了index++,也就是傳遞過(guò)去的這個(gè)receiverManager中的index已經(jīng)等于1了。
然后來(lái)到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);
}
}
}
因?yàn)閭鬟f過(guò)來(lái)的condition為2,不滿足執(zhí)行條件,所以走了else的流程,用傳遞過(guò)來(lái)的receiverManager繼續(xù)執(zhí)行execute(),還是要注意,這個(gè)receiverManager中的index已經(jīng)是等于1的,那么就又回到了ReceiverManager的代碼中:
public void execute(String condition, IBaseReceiver receiverManager) {
...
//此時(shí)index為1,receiver為Receiver2的實(shí)例對(duì)象
IBaseReceiver receiver = receivers.get(index);
index++;
receiver.execute(condition, receiverManager);
}
因?yàn)?code>receiverManager一直是同一個(gè)對(duì)象,只是傳遞來(lái)傳遞去,沒(méi)有new,所以這里的index為1,拿到的receiver為Receiver2的實(shí)例對(duì)象,那么就進(jìn)入了Receiver2的execute(),這里邏輯就不再貼了,跟進(jìn)入Receiver1的是一樣的,只是判斷條件不同,因?yàn)闂l件滿足,Receiver2直接處理了任務(wù),不再繼續(xù)進(jìn)行,如果條件還是不滿足,繼續(xù)Receiver3,這么一直循環(huán)下去。
還是亂的話,跟著代碼理一下,其實(shí)很簡(jiǎn)單很清晰,也有點(diǎn)妙。
這種設(shè)計(jì)模式的使用也很常見(jiàn),Android源碼中的事件傳遞,Okhttp中的攔截器,好多好多,都是使用到。