責(zé)任鏈模式(Chain of Responsibility Pattern)

責(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、Receiver3Receiver3

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表示。
然后是Receiver1Receiver3、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)了IBaseReceiverreceiverManager,肯定是不理解為什么,這里看一下這個(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)入到ReceiverManagerexecute ()方法:

    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í)行Receiver1execute(),并且還是把這個(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)入了Receiver2execute(),這里邏輯就不再貼了,跟進(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中的攔截器,好多好多,都是使用到。

項(xiàng)目地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容