戳藍字「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】閱讀更多精彩好文。