不少框架如mybatis的插件,servlet的filter,dubbo,安全框架諸如Spring security、apache shiro都會用到設計模式中的責任鏈模式,因此學習責任鏈模式成爲幫助你學習以上這些框架的一個好的手段之一。今天咱們就來了解一下責任鏈模式。html
若是有多個對象(Handler)都有機會處理數據源(RequestSource,這裏不是單純的數據庫數據源,能夠是一個請求,總之是來源),責任鏈可使數據的發送者和接收者解耦,數據沿着責任鏈傳遞,直到有一個對象處理了它爲止。 上去造成了一條流水線的鏈條,因此稱之爲責任鏈,可是不單單侷限於鏈條,還能夠成樹形或者環形,這取決於你的業務設計。數據庫
插件設計、攔截器、過濾器等一些針對切入點的特定鏈式處理。均可以使用責任鏈模式。apache
兩種方式的不一樣主要是定義處理鏈的順序和結構的不一樣,接下來咱們來看看這三種方式。設計模式
好處在於能夠集中管理處理器,指責單一。很是容易理解,容易實現。缺點是若是新增處理器(Handler)勢必影響已有的處理器,只能順序執行。處理流程是這樣的:安全
接下來用代碼來實現一下此模式:bash
HandlerChain 負責維護調用鏈條的順序,這裏默認實現用List來管理Handlermybatis
public interface HandlerChain {
/**
* 調用handler 處理 source.
*
* @param requestSource the request source
*/
void doChain(RequestSource requestSource);
}
// 實現
public class DefaultHandlerChain implements HandlerChain {
// 當前handler指針的位置
private int pos = 0;
private List<Handler> handlers = new ArrayList<>();
public void addHandler(Handler handler) {
handlers.add(handler);
}
@Override
public void doChain(RequestSource requestSource) {
int size = handlers.size();
if (pos < size) {
//注意對pos的處理
Handler handler = handlers.get(pos++);
handler.doHandler(requestSource, this);
}
}
}
複製代碼
Handler是處理鏈的節點抽象,是數據源(RequestSource)的具體處理者,它負責對數據的處理以及決定是否進入下一個Handler。框架
public interface Handler {
/**
* Do handler.
*
* @param requestSource 數據源
* @param handlerChain 傳入當前的Chain進行相似遞歸式的調用。
*/
void doHandler(RequestSource requestSource,HandlerChain handlerChain);
}
// 其中一個實現
public class HeaderHandler implements Handler {
@Override
public void doHandler(RequestSource requestSource, HandlerChain handlerChain) {
// 處理數據
Integer header = requestSource.getHeader();
System.out.println("header handler= " + header);
//繼續下一個 你能夠根據條件來決定是否繼續進行chain
handlerChain.doChain(requestSource);
}
}
複製代碼
這裏利用了鏈表的一部分特色,經過在當前的Handler指定下一個Handler來做爲指針,相比較上面而言,Handler更自治,在節點的處理上更加靈活。ide
Handler負責指針以及邏輯處理:學習
public interface Handler {
/**
* 指針指向下一個處理節點.
*
* @return the next
*/
Handler getNext();
/**
* 處理具體邏輯.
*
* @param requestSource the request source
*/
void doHandler(RequestSource requestSource);
}
// 實現
public class HeaderHandler implements Handler {
private Handler next;
public HeaderHandler(Handler next) {
this.next = next;
}
@Override
public Handler getNext() {
return next;
}
@Override
public void doHandler(RequestSource requestSource) {
Integer header = requestSource.getHeader();
System.out.println("header = " + header);
if (next != null) {
next.doHandler(requestSource);
}
}
}
複製代碼
責任鏈模式在各類常見框架中很是常見。因此建議各位在對此設計模式進行認真學習。
原創做者:碼農小胖哥 轉載地址:gper.club/articles/7e…