漫畫設計模式:什麼是 “職責鏈模式” ?

Python實戰社羣

Java實戰社羣

長按識別下方二維碼,按需求添加

掃碼關注添加客服

進Python社羣▲

掃碼關注添加客服

進Java社羣

作者丨小灰

來源丨程序員小灰(ID:chengxuyuanxiaohui)

—————  第二天  —————


————————————

在一家公司裏,有三個程序員,他們的名字分別是小A、小B、小C:

有一天,公司新來的產品經理有一個新需求,但她不知道這個需求應該由誰來負責。於是,她首先找到了小A:

於是,產品經理又找到了小B:

於是,產品經理又找到了小C:

像這樣,一個任務從小A轉移到小B,從小B轉移到小C,再由小C最終處理,形成了一個完整的任務處理鏈條:

在上面這個鏈條當中,包含着不同的任務處理者。面對一個新任務,每個任務處理者需要判斷自己能否處理該任務,如果能處理,則處理並返回;如果不能處理,則轉交給下一個任務處理者,直到某一個任務處理者最終完成處理。這就是職責鏈模式的核心思想。


abstract public class Handler {

    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    abstract String handleRequest(String msg);
}

從上面這個抽象類可以看出,每一個Handler對象都包含着一個successor成員,指向它的下一個任務處理者,就像鏈表節點的next指針一樣。

public class HandlerA extends Handler {
    @Override
    String handleRequest(String msg) {
        if(msg.contains("a")){
            msg = msg.replace('a', '*');
        } else if(this.successor != null){
            msg = this.successor.handleRequest(msg);
        }
        return msg;
    }
}

public class HandlerB extends Handler {
    @Override
    String handleRequest(String msg) {
        if(msg.contains("b")){
            msg = msg.replace('b', '*');
        } else if(this.successor != null){
            msg = this.successor.handleRequest(msg);
        }
        return msg;
    }
}

public class HandlerC extends Handler {
    @Override
    String handleRequest(String msg) {
        if(msg.contains("c")){
            msg = msg.replace('c', '*');
        } else if(this.successor != null){
            msg = this.successor.handleRequest(msg);
        }
        return msg;
    }
}

在這三個Handler實現類中,做了相似的判斷:

如果傳入的消息字符串包含某個字母,則把對應的字母替換成*。一旦某個Handler替換了自己所負責的字母,就直接結束整個鏈路;如果沒有自己所負責的字母,則指定下一個Handler繼續處理。

public class Client {

    public static void main(String[] args) {
        Handler handlerA = new HandlerA();
        Handler handlerB = new HandlerB();
        Handler handlerC = new HandlerC();

        handlerA.setSuccessor(handlerB);
        handlerB.setSuccessor(handlerC);

        System.out.println(handlerA.handleRequest("apple"));
        System.out.println(handlerA.handleRequest("bicycle"));
        System.out.println(handlerA.handleRequest("color"));
    }
}

在客戶端代碼中,可以靈活設置整個鏈路和處理者的次序,然後直接調用第一個處理者的handleRequest方法,就相當於啓動了整個鏈路。


做過Web開發的小夥伴都知道,當客戶端對Web應用發出HTTP請求的時候,會首先經過Tomcat容器的一層層過濾器(Filter),過濾器會針對請求的訪問權限、參數合法性等方面進行驗證和過濾。

這一層一層過濾器的實現,就使用了職責鏈模式。

熟悉SpringMVC框架源碼的小夥伴應該都知道,客戶端的HTTP請求到了Web應用之後,會被SpringMVC框架的DispatcherServlet類進行分發,分發給Controller層的具體方法。

在進入Controller層的業務邏輯之前,以及執行完業務邏輯之後,該請求都會經過一系列的攔截器(Interceptor)。這一系列攔截器的處理流程,也同樣是職責鏈模式的實現。

—————END—————

程序員專欄 掃碼關注填加客服 長按識別下方二維碼進羣

近期精彩內容推薦:  

 阿里、京東、美團……背後的共同金主

 沸騰了!蘇寧全員漲薪,每月最高多1萬6!

 大白話java多線程,高手勿入

 用Python完成Excel合併(拆分)的各種操作


在看點這裏好文分享給更多人↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章