設計模式之責任鏈模式(Chain of Responsibility)

  • 引入責任鏈模式
  • 責任鏈模式的實例
  • 責任鏈模式的分析
  • 責任鏈模式的優勢
  • 責任鏈模式的應用

引入責任鏈模式

責任鏈模式描述的就是如何推卸責任,說的簡潔點,就是踢皮球哈哈。舉個例子,有時候,出了某件事,我們去解決,找到A,結果A踢皮球,說這不關我的事,去找B解決,然后我們就去找B,結果B也說,這跟我沒關系,快去找C,就這樣,我們就被踢來踢去,這就是責任鏈模式的思想,在找到正確的人解決之前,我們被不斷的踢給一個有一個人,就是推卸責任。
上面的例子,可能有點貶義,但在實際編程中,有時候確實存在需要推卸責任的情況,,比如,當我們接受到一個請求時,當前的程序暫時無法處理這個請求,于是就需要把請求給別人去處理。如果是web開發人員,對此應該很熟悉,當服務器收到一個客戶端的請求時,首先會解析請求,action層不會處理請求,而是將請求的參數等信息進行簡單的解析處理,然后根據請求的內容信息等將請求具體轉發給service去處理。
當一個人被要求做一件事的時候,如果他自己可以做,那他就自己做了,如果他自己做不了,那就轉發給另一個人做,另一個人也是一樣,如果他自己可以做,就做,不可以做,就給別人做。。。。。。
這就是責任鏈模式的基本思想

責任鏈模式的實例

實例的類圖

image.png

Support是一個抽象類,他的核心方法support中,如果當前support可以解決,就解決,如果不行,就交給next去解決。

package ChainOfResponse;

public abstract class Support {
    private String name;
    private Support next;
    
    public Support(String name) {
        this.name = name;
    }
    
    public Support setNext(Support next) {
        this.next = next;
        return next;
    }
    
    public final void support(Trouble trouble) {
        if(resolve(trouble)) {
            done(trouble);
        } else if (next != null) {
            next.support(trouble);
        } else {
            fail(trouble);
        }
    }
    
    public String toString() {              // 顯示字符串
        return "[" + name + "]";
    }
    
    protected abstract boolean resolve(Trouble trouble);
    
    protected void done(Trouble trouble) {
        System.out.println(trouble + " is resolved by " + this + ".");
    }
    
    protected void fail(Trouble trouble) {  // 未解決
        System.out.println(trouble + " cannot be resolved.");
    }
}

然后我們實現幾個具體的support類
NoSupport類是一個永遠不解決問題的類

package ChainOfResponse;

public class NoSupport extends Support {

    public NoSupport(String name) {
        super(name);
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        return false;
    }
    
}

LimitSupport類,解決指定范圍內的問題

package ChainOfResponse;

public class LimitSupport extends Support {

    private int limit;
    
    public LimitSupport(String name, int limit) {
        super(name);
        this.limit = limit;
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        if(trouble.getNumber() < limit)
            return true;
        return false;
    }
}

OddSupport類,解決奇數的問題

package ChainOfResponse;

public class OddSupport extends Support {

    public OddSupport(String name) {
        super(name);
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        if(trouble.getNumber() % 2 == 1)
            return true;
        return false;
    }
}

package ChainOfResponse;

public class SpecialSupport extends Support {
    
    private int number;
    
    public SpecialSupport(String name, int number) {
        super(name);
        this.number = number;
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        if(trouble.getNumber() == number)
            return true;
        return false;
    }
    
}

,最后實現一個main類:

package ChainOfResponse;

public class Main {

    public static void main(String[] args) {
        
        Support alice   = new NoSupport("Alice");
        Support bob     = new LimitSupport("Bob", 100);
        Support charlie = new SpecialSupport("Charlie", 429);
        Support diana   = new LimitSupport("Diana", 200);
        Support elmo    = new OddSupport("Elmo");
        Support fred    = new LimitSupport("Fred", 300);
        
        alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
        
        for(int i=0;i<500;i+=33) {
            alice.support(new Trouble(i));
        }
    }

}

Main類中定義了一個責任鏈,將幾個support對象連接在一起,組成了一條責任鏈,然后去處理問題
運行結果如下:

image.png

責任鏈模式的分析

首先,責任鏈模式中,存在著這么幾個角色:

  • Handler處理者
    handler金額use定義了處理請求的接口,handler知道,下一個處理者是誰,如果自己無法處理請求,就轉給下一個處理者。
    在實例中對應的是,support類和support方法

  • concreteHandler(具體的處理者)
    具體的處理者是處理請求的具體角色。
    在此實例中,由NoSupport角色和其他幾個類扮演

  • Client
    請求者角色,就是向第一個具體的handler發送請求的角色,并連接好責任鏈,實例中對應的是main類的main方法。

責任鏈模式的類圖如下:

image.png

責任鏈的作用

  • 弱化了發出請求的人和處理請求的人之間的關系
    發出請求的人只需要向第一個具體的處理者發送請求,然后就可以不用管了,處理者會在責任鏈上自己尋找處理的方法。
    這樣就解耦了處理者和請求者之間的關系。
    如果我們不采取責任鏈模式,那么請求者就必須要很清楚哪個處理者能處理它的請求,就必須對所有的處理者都有所了解,類似于上帝視角,然而在實際中,要求請求這了解這么多是不實際的

  • 可以動態的改變責任鏈
    責任鏈還有的好處就是可以動態的改變責任,刪除或者添加或者改變順序。

  • 讓各個處理者專注于實現自己的職責
    責任鏈模式同時還做到了處理者之間的解耦,處理者自己專注于自己的處理邏輯就好,不管其他處理者干什么。

  • 推卸責任也可能導致處理延遲
    我們可以責任鏈模式需要在責任鏈上傳播責任,直至找到合適的處理對象。這樣提高了程序的靈活性,但同時也出現了處理的延遲,因為有一個尋找的過程。所以需要低延遲的情況下,就不應該使用責任鏈模式

責任鏈模式的應用

在視窗系統中,經常會使用到責任鏈模式,尤其是事件的處理,熟悉javascript開發的朋友,可能會知道,瀏覽器中的事件有冒泡機制,,就是事件的是向父控件傳播的,如果自己處理不了,就會傳播給父控件去處理。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容