責任鏈的2種實現方式,你更pick哪一種

 戳藍字「TopCoder」關注我們哦!

編者注:責任鏈模式是日常開發或者框架中經常被使用的一種設計模式,典型的責任鏈有2種實現方式,不知道各位小夥伴更pick哪一種呢?下面就一起來比較下這2種實現方式吧~

1 責任鏈是什麼

責任鏈是屬於行爲型模式,在這種模式中,通常每個接收者都包含對另一個接收者的引用,如果一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。責任鏈模式避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿着這條鏈傳遞請求,直到有對象處理它爲止。

責任鏈類圖下圖:

責任鏈模式在開源項目中應用場景還是比較常見的,比如Tomcat中的Filter處理鏈、Netty中的ChannelHandler處理鏈、Dubbo RPC中的consumer側的Filter鏈等等。責任鏈模式應用在業務流程中的 多個同類型操作場景,相當於對一個複雜較長的操作進行分段處理,這樣對擴展性友好,新增操作階段時更加靈活。這種可以理解爲分片思想,降低業務流程操作的複雜度。

2 責任鏈的2種實現

常見的責任鏈流程如下:

2.1 節點傳遞方式

節點傳遞方式也就是,責任鏈中當前節點處理完成之後,自己傳遞給下一個處理節點繼續處理。

public interface Handler {
    default boolean match(String msg) {
        return true;
    }
    void process(String msg);
}

public abstract class AbstractHandler implements Handler {
    private Handler next;

    public AbstractHandler setNextHandler(Handler next) {
        this.next = next;
        return this;
    }

    @Override
    public void process(String msg) {
        doProcess(msg);

        if (next != null) {
            next.process(msg);
        }
    }

    protected abstract void doProcess(String msg);
}

// 具體的責任鏈處理器
public class Handler1 extends AbstractHandler {
    @Override
    public void doProcess(String msg) {
        System.out.println("[Handler1] process " + msg);
    }
}
public class Handler2 extends AbstractHandler {
    @Override
    protected void doProcess(String msg) {
        System.out.println("[Handler2] process " + msg);
    }
}
public class Handler3 extends AbstractHandler {
    @Override
    protected void doProcess(String msg) {
        System.out.println("[Handler3] process " + msg);
    }
}

輸出結果:

2.2 統一傳遞方式

統一傳遞方式也就是,不由責任鏈中處理節點傳遞給下一個節點,而是由統一的傳遞邏輯進行傳遞。

public class HandlerWrap {
    private List<Handler> handlerList = new ArrayList<>();

    public HandlerWrap() {
        handlerList.add(new Handler1());
        handlerList.add(new Handler2());
        handlerList.add(new Handler3());
    }

    public void process(String msg) {
        for (Handler handler : handlerList) {
            handler.process(msg);
        }
    }
}

public class Handler1 implements Handler {
    @Override
    public void process(String msg) {
        System.out.println("[Handler1] process " + msg);
    }
}
public class Handler2 implements Handler {
    @Override
    public void process(String msg) {
        System.out.println("[Handler2] process " + msg);
    }
}
public class Handler3 implements Handler {
    @Override
    public void process(String msg) {
        System.out.println("[Handler3] process " + msg);
    }
}

輸出結果:

3 兩種實現方式的比較

上述兩種實現方式差別就是誰來進行下一個節點的傳遞工作,節點傳遞方式 是責任鏈中當前處理節點處理完成之後,自己傳遞給下一個節點;統一傳遞方式 是在統一的地方進行傳遞工作,減輕處理節點的“負擔”。

二者本質上是一樣的,不過前一種實現方式初始化成本較高,還要注意處理節點的前後順序,這種調整一個節點的位置時特別要注意前後節點的關係,否則處理鏈順序就錯亂了。

後續開發中,建議使用第二種實現方式,這種責任鏈初始化成本較低,調整責任鏈成本較小。不過有些責任鏈使用場景中,會將前一個處理節點的返回結果作爲下一個處理節點的入參,這種場景一般推薦使用第一種實現方式,就像Netty中的ChannelHandler處理鏈流程類似。

如果小夥伴們還知道其他實現方式或者更多的應用場景,歡迎留言討論哈~

 推薦閱讀 


歡迎小夥伴關注【TopCoder】閱讀更多精彩好文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章