設計模式之責任鏈模式講解

前言

不少框架如mybatis,servlet的filter,dubbo,安全框架諸如Spring security、apache shiro都會用到設計模式中的責任鏈模式,因此學習責任鏈模式成爲幫助你學習以上這些框架的一個好的手段之一。今天咱們就來了解一下責任鏈模式。java

定義

若是有多個對象(Handler)都有機會處理數據源(RequestSource,這裏不是單純的數據庫數據源,能夠是一個請求,總之是來源),責任鏈可使數據的發送者和接收者解耦,數據沿着責任鏈傳遞,直到有一個對象處理了它爲止。
上去造成了一條流水線的鏈條,因此稱之爲責任鏈,可是不單單侷限於鏈條,還能夠成樹形或者環形,這取決於你的業務設計。數據庫

場景

插件設計、攔截器、過濾器等一些針對切入點的特定鏈式處理。均可以使用責任鏈模式。apache

兩種實現方式

兩種方式的不一樣主要是定義處理鏈的順序和結構的不一樣,接下來咱們來看看這兩種方式。segmentfault

經過處理器集合來定義處理順序

好處在於能夠集中管理處理器,指責單一。很是容易理解,容易實現。缺點是若是新增處理器(Handler)勢必影響已有的處理器,只能順序執行。處理流程是這樣的:設計模式

接下來用代碼來實現一下此模式:安全

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);
        }
    }
}

總結

責任鏈模式在各類常見框架中很是常見。因此建議各位在對此設計模式進行認真學習。相關代碼在公衆號:Felordcn 同名文章中提供。

關注公衆號:碼農小胖哥 獲取更多資訊

相關文章
相關標籤/搜索