責任鏈模式
一、定義
使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈條傳遞該請求,直到有對象處理它
責任鏈的通用類
責任鏈模式的核心在“鏈”上,“鏈”是由多個處理者ConcreteHandler組成
責任鏈的通用源碼
-
抽象處理者
public abstract class Handler { private Handler nextHandler; //每個處理者都必須對請求做出處理 public final Response handleMessage(Request request){ Response response = null; //判斷是否是自己的處理級別 if(this.getHandlerLevel().equals(request.getRequestLevel())){ response = this.echo(request); }else{ //不屬於自己的處理級別 //判斷是否有下一個處理者 if(this.nextHandler != null){ response = this.nextHandler.handleMessage(request); }else{ //沒有適當的處理者,業務自行處理 } } return response; } //設置下一個處理者是誰 public void setNext(Handler _handler){ this.nextHandler = _handler; } //每個處理者都有一個處理級別 protected abstract Level getHandlerLevel(); //每個處理者都必須實現處理任務 protected abstract Response echo(Request request); }
抽象的處理者實現三個職責:
- 一是定義一個請求的處理方法handleMessage,唯一對外開
放的方法; - 二是定義一個鏈的編排方法setNext,設置下一個處理者;
- 三是定義了具體的請求者必須實現的兩個方法:
- 定義自己能夠處理的級別getHandlerLevel
- 具體的子類的處理任務echo
- 一是定義一個請求的處理方法handleMessage,唯一對外開
-
具體處理者
public class ConcreteHandler1 extends Handler { //定義自己的處理邏輯 protected Response echo(Request request) { //完成處理邏輯 return null; } //設置自己的處理級別 protected Level getHandlerLevel() { //設置自己的處理級別 return null; } }
public class ConcreteHandler2 extends Handler { //定義自己的處理邏輯 protected Response echo(Request request) { //完成處理邏輯 return null; } //設置自己的處理級別 protected Level getHandlerLevel() { //設置自己的處理級別 return null; } }
在處理者中涉及三個類:
- Level類負責定義請求和處理級別,
- Request類負責封裝請求,
- Response負責封裝鏈中返回的結果
該三個類都需要根據業務產生
-
場景類
public class Client { public static void main(String[] args) { //聲明所有的處理節點 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); //設置鏈中的階段順序1-->2-->3 handler1.setNext(handler2); handler2.setNext(handler3); //提交請求,返回結果 Response response = handler1.handlerMessage(new Request()); } }
二、責任鏈模式的優點
-
將請求跟處理分開。
請求者可以不用知道是誰處理的,處理者可以不同這道請求的全貌,兩者解耦,提高系統的靈活性
三、責任鏈模式的缺點
-
性能問題
每個請求都是從鏈頭遍歷到鏈尾,特別是在比鏈比較長的時候,性能會是一個非常大的問題
-
調試不方便
當鏈條比較長,環節比較多時,由於採用了類似遞歸的方式,調試的時候邏輯可能比較複雜
注意,鏈接中節點數量需要控制,避免出現超長鏈的情況,一般的做法是在Handler中設置一個最大節點數量,在setNext中判斷是否超過其閾值,以此決定是否允許該鏈建立