設(shè)計(jì)模式之責(zé)任鏈模式(Chain of Responsibility Pattern)

What:

責(zé)任鏈模式也叫職責(zé)鏈模式瞪醋。為了避免請求發(fā)送者與多個(gè)請求處理者耦合在一起爵政,將所有請求的處理者通過前一對象記住其下一個(gè)對象的引用而連成一條鏈矛物;當(dāng)有請求發(fā)生時(shí)霹琼,可將請求沿著這條鏈傳遞蓬抄,直到有對象處理它為止丰嘉。

Why:

優(yōu)點(diǎn):

1.降低耦合度。它將請求的發(fā)送者和接收者解耦嚷缭。
2.增強(qiáng)給對象指派職責(zé)的靈活性饮亏。通過改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,允許動(dòng)態(tài)地新增或者刪除責(zé)任阅爽。

缺點(diǎn):

1.責(zé)任鏈太長或者每條鏈判斷處理的時(shí)間太長會(huì)影響性能路幸。特別是遞歸循環(huán)的時(shí)候
2.職責(zé)鏈建立的合理性要靠客戶端來保證,增加了客戶端的復(fù)雜性付翁,可能會(huì)由于職責(zé)鏈的錯(cuò)誤設(shè)置而導(dǎo)致系統(tǒng)出錯(cuò)简肴,如可能會(huì)造成循環(huán)調(diào)用。
3.不能保證每個(gè)請求一定被處理百侧。由于一個(gè)請求沒有明確的接收者砰识,所以不能保證它一定會(huì)被處理,該請求可能一直傳到鏈的末端都得不到處理佣渴。

Where:

1.有多個(gè)對象可以處理一個(gè)請求辫狼,哪個(gè)對象處理該請求由運(yùn)行時(shí)刻自動(dòng)確定。
2.可動(dòng)態(tài)指定一組對象處理請求观话,或添加新的處理者予借。
3.在不明確指定請求處理者的情況下,向多個(gè)處理者中的一個(gè)提交請求频蛔。

How:

職責(zé)鏈模式主要包含以下角色:

抽象處理者(Handler)角色: 定義一個(gè)處理請求的接口灵迫,包含抽象處理方法和一個(gè)后繼連接。

具體處理者(Concrete Handler)角色: 實(shí)現(xiàn)抽象處理者的處理方法晦溪,判斷能否處理本次請求瀑粥,如果可以處理請求則處理,否則將該請求轉(zhuǎn)給它的后繼者三圆。

客戶類(Client)角色: 創(chuàng)建處理鏈狞换,并向鏈頭的具體處理者對象提交請求避咆,它不關(guān)心處理細(xì)節(jié)和請求的傳遞過程。

示例:模擬程序員提交功能給測試人員修噪,測試人員覺得沒問題之后提交給技術(shù)總監(jiān)查库,技術(shù)總監(jiān)都覺得沒問題后才會(huì)通知老板,老板滿意之后就可以上線了黄琼。

ChainOfResponsibilityPattern-SampleUml

ReviewPerson(抽象處理者角色):

public abstract class ReviewPerson {
    protected ReviewPerson person;

    abstract void handle(String program);

    public ReviewPerson getPerson() {
        return person;
    }

    public void setPerson(ReviewPerson person) {
        this.person = person;
    }
}

Tester樊销、CTO、Boss(具體處理者角色):

public class Tester extends ReviewPerson{
    private final String NAME = "測試人員";
    @Override
    void handle(String program) {
        if("沒有Bug的功能脏款!".equals(program)){
            System.out.println(NAME + ":沒問題围苫,提交給技術(shù)總監(jiān)...");
            getPerson().handle(program);
        }else {
            System.out.println(NAME + ":有Bug呀,再改改撤师!");
        }
    }
}
public class CTO extends ReviewPerson{
    private final String NAME = "技術(shù)總監(jiān)";
    @Override
    void handle(String program) {
        if("沒有Bug的功能剂府!".equals(program)){
            System.out.println(NAME + ":沒問題,提交給老板...");
            getPerson().handle(program);
        }else {
            System.out.println(NAME + ":有Bug呀剃盾,再改改腺占!");
        }
    }
}
public class Boss extends ReviewPerson{

    private final String NAME = "老板";

    @Override
    void handle(String program) {
        if("沒有Bug的功能!".equals(program)){
            System.out.println(NAME + ":功能完成万俗,可以上線了湾笛!");
        }else {
            System.out.println(NAME + ":有Bug呀饮怯,再改改闰歪!");
        }
    }
}

Programmer(客戶類角色):

public class Programmer {
    public static void main(String[] args) {
        ReviewPerson tester = new Tester();
        ReviewPerson cto = new CTO();
        ReviewPerson boss = new Boss();

        tester.setPerson(cto);
        cto.setPerson(boss);

        tester.handle("沒有Bug的功能!");
    }
}

輸出結(jié)果:

測試人員:沒問題蓖墅,提交給技術(shù)總監(jiān)...
技術(shù)總監(jiān):沒問題库倘,提交給老板...
老板:功能完成,可以上線了论矾!

總結(jié)

我認(rèn)為責(zé)任鏈模式的好處在于客戶端不需要知道處理請求的內(nèi)部實(shí)現(xiàn)教翩,而是交給處理者內(nèi)部相互之間的調(diào)用。不過需要注意的是職責(zé)鏈不能過長贪壳,否則可能會(huì)導(dǎo)致性能下降饱亿,并且還需要保證請求一定會(huì)被處理,不要出現(xiàn)像“踢皮球”一樣闰靴,踢著踢著就沒下文了彪笼。

了解更多設(shè)計(jì)模式:

設(shè)計(jì)模式系列

參考資料:

http://c.biancheng.net/view/1383.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蚂且,隨后出現(xiàn)的幾起案子配猫,更是在濱河造成了極大的恐慌,老刑警劉巖杏死,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泵肄,死亡現(xiàn)場離奇詭異捆交,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)腐巢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門品追,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冯丙,你說我怎么就攤上這事诵盼。” “怎么了银还?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵风宁,是天一觀的道長。 經(jīng)常有香客問我蛹疯,道長戒财,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任捺弦,我火速辦了婚禮饮寞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘列吼。我一直安慰自己幽崩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布寞钥。 她就那樣靜靜地躺著慌申,像睡著了一般。 火紅的嫁衣襯著肌膚如雪理郑。 梳的紋絲不亂的頭發(fā)上蹄溉,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音您炉,去河邊找鬼柒爵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赚爵,可吹牛的內(nèi)容都是我干的棉胀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼冀膝,長吁一口氣:“原來是場噩夢啊……” “哼唁奢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起畸写,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤驮瞧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后枯芬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體论笔,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡采郎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狂魔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒜埋。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖最楷,靈堂內(nèi)的尸體忽然破棺而出整份,到底是詐尸還是另有隱情,我是刑警寧澤籽孙,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布烈评,位于F島的核電站,受9級特大地震影響犯建,放射性物質(zhì)發(fā)生泄漏讲冠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一适瓦、第九天 我趴在偏房一處隱蔽的房頂上張望竿开。 院中可真熱鬧,春花似錦玻熙、人聲如沸否彩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽列荔。三九已至,卻和暖如春称杨,著一層夾襖步出監(jiān)牢的瞬間肌毅,已是汗流浹背筷转。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工姑原, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呜舒。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓锭汛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袭蝗。 傳聞我的和親對象是個(gè)殘疾皇子唤殴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容