責(zé)任鏈模式

定義

使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系薄料。將這些對(duì)象連成一條鏈获诈,并沿著這條鏈傳遞該請(qǐng)求仍源,直到有對(duì)象處理它為止。

責(zé)任鏈模式.png

如果存在一種層次關(guān)系舔涎,通過(guò)責(zé)任鏈建立邏輯關(guān)系笼踩,較少因某種特定的if判斷。同時(shí)在客戶端修改責(zé)任層級(jí)關(guān)系就可以改變邏輯亡嫌,不用再邏輯代碼中修改嚎于;比較靈活。

不用責(zé)任鏈模式的處理方式:

public void test(int i, Request request){  
    if(i==1){  
        Handler1.response(request);  
    }else if(i == 2){  
        Handler2.response(request);  
    }else if(i == 3){  
        Handler3.response(request);  
    }else if(i == 4){  
        Handler4.response(request);  
    }else{  
        Handler5.response(request);  
    }  
} 

這種方法的優(yōu)點(diǎn)是非常直觀挟冠,簡(jiǎn)單明了于购,并且比較容易維護(hù),但是這種方法也存在著幾個(gè)比較令人頭疼的問(wèn)題:

  • 代碼臃腫:實(shí)際應(yīng)用中的判定條件通常不是這么簡(jiǎn)單地判斷是否為1或者是否為2知染,也許需要復(fù)雜的計(jì)算肋僧,也許需要查詢數(shù)據(jù)庫(kù)等等,這就會(huì)有很多額外的代碼控淡,如果判斷條件再比較多嫌吠,那么這個(gè)if…else…語(yǔ)句基本上就沒(méi)法看了。

  • 耦合度高:如果我們想繼續(xù)添加處理請(qǐng)求的類掺炭,那么就要繼續(xù)添加else if判定條件辫诅;另外,這個(gè)條件判定的順序也是寫(xiě)死的涧狮,如果想改變順序泥栖,那么也只能修改這個(gè)條件語(yǔ)句簇宽。

原理:

在上面的需求中,如果滿足條件1,則由Handler1來(lái)處理吧享,不滿足則向下傳遞魏割;如果滿足條件2,則由Handler2來(lái)處理钢颂,不滿足則繼續(xù)向下傳遞钞它,以此類推,直到條件結(jié)束殊鞭。把判定條件的部分放到處理類中遭垛,這就是責(zé)任連模式的原理。

角色

  • 抽象處理類Handler:
    抽象處理類中主要包含一個(gè)指向下一處理類的成員變量nextHandler和一個(gè)處理請(qǐng)求的方法handRequest操灿,handRequest方法的主要主要思想是锯仪,如果滿足處理的條件,則有本處理類來(lái)進(jìn)行處理趾盐,否則由nextHandler來(lái)處理庶喜。
  • 具體處理類:
    具體處理類主要是對(duì)具體的處理邏輯和處理的適用條件進(jìn)行實(shí)現(xiàn)。

代碼

抽象處理類

abstract class Handler {  
    private Handler nextHandler;      
    public final Response handleRequest(Request request){  
        Response response = null;  
          
        if(this.getHandlerLevel().above(request.getLevel())){  
            response = this.response(request);  
        }else{  
            if(this.nextHandler != null){  
                this.nextHandler.handleRequest(request);  
            }else{  
                System.out.println("-----沒(méi)有合適的處理器-----");  
            }  
        }  
        return response;  
    }  
    public void setNextHandler(Handler handler){  
        this.nextHandler = handler;  
    }  
    protected abstract Level getHandlerLevel();  
    public abstract Response response(Request request);  
}  

具體處理類1

class ConcreteHandler1 extends Handler {  
    protected Level getHandlerLevel() {  
        return new Level(1);  
    }  
    public Response response(Request request) {  
        System.out.println("-----請(qǐng)求由處理器1進(jìn)行處理-----");  
        return null;  
    }  
}  

具體處理類2

class ConcreteHandler2 extends Handler {  
    protected Level getHandlerLevel() {  
        return new Level(3);  
    }  
    public Response response(Request request) {  
        System.out.println("-----請(qǐng)求由處理器2進(jìn)行處理-----");  
        return null;  
    }  
}  

具體處理類3

class ConcreteHandler3 extends Handler {  
    protected Level getHandlerLevel() {  
        return new Level(5);  
    }  
    public Response response(Request request) {  
        System.out.println("-----請(qǐng)求由處理器3進(jìn)行處理-----");  
        return null;  
    }  
}  

其他

class Level {  
    private int level = 0;  
    public Level(int level){  
        this.level = level;  
    };  
      
    public boolean above(Level level){  
        if(this.level >= level.level){  
            return true;  
        }  
        return false;  
    }  
}  
class Request {  
    Level level;  
    public Request(Level level){  
        this.level = level;  
    }  
      
    public Level getLevel(){  
        return level;  
    }  
}  
  
class Response {  
  
}

客戶端

public class Client {  
    public static void main(String[] args){  
        Handler handler1 = new ConcreteHandler1();  
        Handler handler2 = new ConcreteHandler2();  
        Handler handler3 = new ConcreteHandler3();  
  
        handler1.setNextHandler(handler2);  
        handler2.setNextHandler(handler3);  
       
        Response response = handler1.handleRequest(new Request(new Level(4)));  
    }  
} 

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

責(zé)任鏈模式與if…else…相比救鲤,他的耦合性要低一些久窟,因?yàn)樗褩l件判定都分散到了各個(gè)處理類中,并且這些處理類的優(yōu)先處理順序可以隨意設(shè)定本缠。責(zé)任鏈模式也有缺點(diǎn)斥扛,這與if…else…語(yǔ)句的缺點(diǎn)是一樣的,那就是在找到正確的處理類之前丹锹,所有的判定條件都要被執(zhí)行一遍稀颁,當(dāng)責(zé)任鏈比較長(zhǎng)時(shí),性能問(wèn)題比較嚴(yán)重楣黍。

適用場(chǎng)景

就像開(kāi)始的例子那樣峻村,假如使用if…else…語(yǔ)句來(lái)組織一個(gè)責(zé)任鏈時(shí)感到力不從心,代碼看上去很糟糕時(shí)锡凝,就可以使用責(zé)任鏈模式來(lái)進(jìn)行重構(gòu)粘昨。

總結(jié)

責(zé)任鏈模式其實(shí)就是一個(gè)靈活版的if…else…語(yǔ)句,它就是將這些判定條件的語(yǔ)句放到了各個(gè)處理類中窜锯,這樣做的優(yōu)點(diǎn)是比較靈活了张肾,但同樣也帶來(lái)了風(fēng)險(xiǎn),比如設(shè)置處理類前后關(guān)系時(shí)锚扎,一定要特別仔細(xì)吞瞪,搞對(duì)處理類前后邏輯的條件判斷關(guān)系,并且注意不要在鏈中出現(xiàn)循環(huán)引用的問(wèn)題驾孔。

Android中:

(1)ViewGroup時(shí)間分發(fā)(dispatchTouchEvent)
處理規(guī)則:如果時(shí)間被自己攔截芍秆,就自己處理惯疙,否則傳給子view;
(2)有序廣播(OrderedBroadcast)
普通廣播是異步的妖啥,發(fā)送后可以被所有的接收器接收到霉颠,而且無(wú)法確認(rèn)誰(shuí)先后接收到廣播;
有序廣播是根據(jù)優(yōu)先級(jí)別來(lái)一次傳播的荆虱,中間可以被終止蒿偎;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市怀读,隨后出現(xiàn)的幾起案子诉位,更是在濱河造成了極大的恐慌,老刑警劉巖菜枷,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苍糠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡啤誊,警方通過(guò)查閱死者的電腦和手機(jī)岳瞭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坷衍,“玉大人,你說(shuō)我怎么就攤上這事条舔》愣” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵孟抗,是天一觀的道長(zhǎng)迁杨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)凄硼,這世上最難降的妖魔是什么铅协? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮摊沉,結(jié)果婚禮上狐史,老公的妹妹穿的比我還像新娘。我一直安慰自己说墨,他們只是感情好骏全,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著尼斧,像睡著了一般姜贡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棺棵,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天楼咳,我揣著相機(jī)與錄音熄捍,去河邊找鬼。 笑死母怜,一個(gè)胖子當(dāng)著我的面吹牛余耽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播糙申,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宾添,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了柜裸?” 一聲冷哼從身側(cè)響起缕陕,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疙挺,沒(méi)想到半個(gè)月后扛邑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铐然,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蔬崩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搀暑。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沥阳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出自点,到底是詐尸還是另有隱情桐罕,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布桂敛,位于F島的核電站功炮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏术唬。R本人自食惡果不足惜薪伏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粗仓。 院中可真熱鬧嫁怀,春花似錦、人聲如沸借浊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)巴碗。三九已至朴爬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橡淆,已是汗流浹背召噩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工母赵, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人具滴。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓凹嘲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親构韵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子周蹭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

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