定義
責任鏈模式(Chain of Responsibility Pattern):避免請求發(fā)送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,并且沿著這條鏈傳遞請求,直到有對象處理它為止。職責鏈模式是一種對象行為型模式。
從定義可以看出,責任鏈模式將請求發(fā)送者和處理者解偶,即發(fā)送方不用知道誰來處理他的請求(沒有類依賴),同時集中的處理者結(jié)構(gòu)允許多個處理者共享請求和分布處理,很像流水線加工廠的方式。所以責任鏈模式常常用在過濾器設(shè)計,觸摸事件處理等場景中。
Handler(抽象處理者):它定義了一個處理請求的接口,一般設(shè)計為抽象類,由于不同的具體處理者處理請求的方式不同,因此在其中定義了抽象請求處理方法。抽象處理者需要做兩件事,其一是定義處理接口,二是定義責任鏈的鏈接方式,比如如果處理者之間存在鏈表或者樹狀關(guān)系,則采用鏈表形式,需要在抽象處理者中保留下一個處理者的引用;如果處理者之間彼此邏輯獨立,則可以采用數(shù)組來維持鏈狀結(jié)構(gòu)。
ConcreteHandler(具體處理者):它是抽象處理者的子類,可以處理用戶請求。具體處理者也需要做兩件事,其一是實現(xiàn)自己的處理邏輯,二是表明自己的處理權(quán)限。
代碼
public abstract class IRequestHandler {
public abstract boolean handler(Request request);
}
public class HttpOriginDataIntercept extends IRequestHandler {
@Override
public boolean handler(Request request) {
if (!request.mBaseUrl.startsWith("https")) {
return false;
}
return true;
}
}
public class ContentCheckHander extends IRequestHandler {
@Override
public boolean handler(Request request) {
return !request.mContent.contains("黃賭毒");
}
}
public class RequestHandlerContainer extends IRequestHandler {
List<IRequestHandler> handlers = new ArrayList<>();
public RequestHandlerContainer addHandler(IRequestHandler handler){
handlers.add(handler);
return this;
}
@Override
public boolean handler(Request request) {
for (IRequestHandler handler:
handlers) {
if (!handler.handler(request)) {
return false;
}
}
return true;
}
}
public class Request {
String mBaseUrl;
HashMap<String, String> mHeader;
String mContent;
}
上述代碼中簡單描述一個請求的檢查過程,提供了請求的協(xié)議檢查和內(nèi)容檢查,其檢查鏈上可以動態(tài)增加和刪除檢查實現(xiàn),這里檢查鏈采用了集合來構(gòu)建,因為多個檢查標準沒有邏輯關(guān)系,這個和Arouter中的過濾器很相似。而像Android中的view的事件分發(fā)和處理這種是采用了類的關(guān)聯(lián)來構(gòu)建事件處理鏈。
總結(jié)
職責鏈模式的主要優(yōu)點
- 對象僅需知道該請求會被處理即可,且鏈中的對象不需要知道鏈的結(jié)構(gòu),由客戶端負責鏈的創(chuàng)建,降低了系統(tǒng)的耦合度
- 請求處理對象僅需維持一個指向其后繼者的引用,而不需要維持它對所有的候選處理者的引用,可簡化對象的相互連接
- 在給對象分派職責時,職責鏈可以給我們更多的靈活性,可以在運行時對該鏈進行動態(tài)的增刪改,改變處理一個請求的職責
- 新增一個新的具體請求處理者時無須修改原有代碼,只需要在客戶端重新建鏈即可,符合 "開閉原則"
職責鏈模式的主要缺點
- 一個請求可能因職責鏈沒有被正確配置而得不到處理
- 對于比較長的職責鏈,請求的處理可能涉及到多個處理對象,系統(tǒng)性能將受到一定影響,且不方便調(diào)試
- 可能因為職責鏈創(chuàng)建不當,造成循環(huán)調(diào)用,導致系統(tǒng)陷入死循環(huán)