定義
使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,知道有一個對象處理它爲止。
結構與說明
Handler : 定義職責的接口(定義處理請求的方法、後繼鏈)
ConcreteHandler :實現職責的類(處理請求和繼續轉發)
Client : 指責鏈的客戶端,將請求提交給鏈上的具體對象,由職責鏈處理。
實現
常規的職責鏈接口
public abstract class Handler{
protected Handler successor;
public void setSuccessor(Handler _successor){
this.successor = _successor;
}
public abstract void handleRequest();
}
//簡單的實現
public class ConcreteHandler extends Hander{
public void handleRequest(){
if(boolCondition){
doSomething...
}else{
if(this.successor!=null)
this.successor.handlerRequest();
}
}
}
在相關的實現中,要注意責任鏈的兩個缺點:
- 性能問題,每個請求都是從鏈頭到鏈尾,一旦鏈比較長,性能就是一個大問題。
- 調試問題,由於採用了遞歸的實現方式,一旦鏈長了起來,調試邏輯就會變得複雜。
- 空間問題,函數調用是採用棧的機制,存在深度限制,實現的時候,鏈長被限制
責任鏈模式的處理方式,很好的契合了SRP(單一職責原則)和LoD(迪米特法則),鏈上的每一個元素只處理符合自己要求的請求,它對鏈上的處理方式一無所知,即鏈上每個元素的處理方式是隔離的。
在職責鏈中,一個請求只有一個對象處理,請求一旦被處理,就不會被傳遞下去。
有時候,我們需要請求在鏈中被多個職責對象處理,此時,這種指責鏈稱爲功能鏈,在javaWeb中,filter過濾器是最常見的實現,每一個Http請求都需要經過相應的filter的權限過濾、安全過濾、字符集過濾等,纔會交由servlet真正的去處理。在Tomcat中,其本身的容器就是責任鏈模式