java/android設(shè)計(jì)模式-行為模式之責(zé)任鏈模式

故名思義責(zé)任鏈模式中存在一個(gè)鏈?zhǔn)浇Y(jié)構(gòu),鏈?zhǔn)浇Y(jié)構(gòu):多外節(jié)點(diǎn)首尾相連标捺,每個(gè)節(jié)點(diǎn)都可以被拆分再連接剿另。具體什么是責(zé)任鏈模式呢媚值。它使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求驶鹉,從而避免請(qǐng)求的發(fā)送者和接受者之間的耦合關(guān)系脚囊,將這個(gè)對(duì)象連成一條鏈挨约,并沿著這個(gè)條鏈傳遞該請(qǐng)求噩凹,直到有一個(gè)對(duì)象處理它為止曹锨。將每一個(gè)節(jié)點(diǎn)看作是一個(gè)對(duì)象临扮,每一個(gè)對(duì)象擁有不同的處理邏輯论矾,將一個(gè)請(qǐng)求從鏈?zhǔn)降氖锥伟l(fā)出,沿著鏈的路徑傳遞給每一個(gè)節(jié)點(diǎn)對(duì)象公条,直到有對(duì)象處理這個(gè)請(qǐng)求為止拇囊。
責(zé)任鏈模式看起來(lái)可能比較陌生,可是我們?cè)谌粘i_(kāi)發(fā)卻經(jīng)常碰到這種形式靶橱。

 public void handleSomething(int eventNum){
        switch (eventNum){
            case 1:
//do something
                break;
            case 2:
//do something
                break;
            case 3:
//do something
                break;
                default:
//do something
        }
    }

switch或者if-else這種就是責(zé)任鏈的裸體樣式寥袭,是最簡(jiǎn)單的實(shí)現(xiàn)格式。當(dāng)然這是個(gè)不恰當(dāng)?shù)睦庸匕裕琲f-else嵌套太多传黄,很可能你都看不懂你的代碼。

舉個(gè)粟子

下面給一個(gè)簡(jiǎn)單的例子:
這個(gè)例子很簡(jiǎn)單队寇,一個(gè)抽象的Handler(處理者角色)和一個(gè)繼承Handler的具體實(shí)現(xiàn)者ConcreteHandler膘掰。

類圖

類圖

代碼

Handler類:

public abstract class Handler {
    /**
     * 持有下一個(gè)處理節(jié)點(diǎn)
     */
    protected Handler successor;

    /**
     * 這個(gè)方法是具體的請(qǐng)求處理方法,在這里為了簡(jiǎn)化而沒(méi)有傳入?yún)?shù)
     */
    public abstract void handleRequest();

    /**
     * 取出下一個(gè)節(jié)點(diǎn)的方法
     */
    public Handler getSuccessor() {
        return successor;
    }

    /**
     * 賦值下一個(gè)節(jié)點(diǎn)的方法
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
}

ConcreteHandler 類:

public class ConcreteHandler extends Handler {
    @Override
    public void handleRequest() {
        /**
         * 判斷是否有下個(gè)節(jié)點(diǎn)的責(zé)任處理對(duì)象
         * 如果有,就轉(zhuǎn)發(fā)請(qǐng)求給下一個(gè)責(zé)任處理對(duì)象
         * 如果沒(méi)有识埋,則處理請(qǐng)求
         */
        if (getSuccessor() != null) {
            System.out.println("放過(guò)請(qǐng)求");
            getSuccessor().handleRequest();
        } else {
            System.out.println("處理請(qǐng)求");
        }
    }
}

Cilent類:

public class Client {
    public static void main(String[] args) {
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        handler1.setSuccessor(handler2);
        handler1.handleRequest();
    }
}

Android/java 中應(yīng)用責(zé)任鏈模式的場(chǎng)景

  • 在android比較明顯的就是事件分發(fā)過(guò)程中對(duì)事件的投遞凡伊。嚴(yán)格說(shuō)來(lái),事件投遞并不是嚴(yán)格的責(zé)任鏈模式窒舟,是責(zé)任鏈模式的變種實(shí)現(xiàn)系忙。子 View 的 onTouchEvent 返回 true 代碼消費(fèi)該事件并不再傳遞,false 代表不消費(fèi)并且傳遞到父 ViewGroup 去處理惠豺,這些樹(shù)形結(jié)構(gòu)的子 View 就是責(zé)任鏈上一個(gè)個(gè)處理對(duì)象银还;
  • OrderedBroadcast,廣播的每一個(gè)接收者按照優(yōu)先級(jí)依次接受消息洁墙,如果處理完成之后可以調(diào)用 abortBroadcast 終止廣播蛹疯,不是自己處理的就可以傳遞給下一個(gè)處理者;
  • try-catch語(yǔ)句热监,每一個(gè) catch 根據(jù) Exception 類型進(jìn)行匹配捺弦,形成一個(gè)責(zé)任鏈,如果有一個(gè) catch 語(yǔ)句與該 Exception 符合孝扛,這個(gè) Exception 就交由給它進(jìn)行處理羹呵,之后所有 catch 語(yǔ)句都不會(huì)再次執(zhí)行。

再來(lái)看看具體的粟子

如果一個(gè)程序員一個(gè)月連續(xù)加班疗琉,這個(gè)月算下來(lái)可以調(diào)休5天。然后這個(gè)coder寫(xiě)了調(diào)休申請(qǐng)給項(xiàng)目經(jīng)理歉铝,可項(xiàng)目經(jīng)理有點(diǎn)方了盈简,他只能審批調(diào)休一天的,然后項(xiàng)目經(jīng)理把你的申請(qǐng)交給部門(mén)經(jīng)理太示,部門(mén)經(jīng)理一看也沒(méi)法柠贤,公司規(guī)則多,他只能審批多超過(guò)三天的类缤,只能讓總經(jīng)理過(guò)目了臼勉。
那看看具體代碼。

//這個(gè)是leader的抽象類
public abstract class Leader {
    private Leader successor;
    private int hoildayNum;
    private String position;

    public void setPosition(String position) {
        this.position = position;
    }

    public String getPosition() {
        return position;
    }

    public Leader(int hoildayNum) {
        this.hoildayNum = hoildayNum;
    }

    public abstract void reply(Worker worker);

    public void handleRequest(Worker worker) {
        if (worker.getHolidayNum() <= hoildayNum) {
            reply(worker);
        } else {
            if (null != successor) {
                successor.handleRequest(worker);
            } else {
                System.out.println(position + "拒絕了你的請(qǐng)求");
            }
        }
    }

    public void setSuccessor(Leader successor) {
        this.successor = successor;
    }
}
/**
 * 項(xiàng)目經(jīng)理處理類
 */
public class ProjectDirector extends Leader {

    public ProjectDirector(int hoildayNum) {
        super(hoildayNum);
        setPosition("項(xiàng)目經(jīng)理");
    }

    @Override
    public void reply(Worker worker) {
        System.out.println(getPosition() + "已通過(guò)你的請(qǐng)求");
    }
}
/**
 * 部門(mén)經(jīng)理處理類
 */
public class DepartmentManager extends Leader {
 public DepartmentManager(int hoildayNum) {
        super(hoildayNum);
        setPosition("部門(mén)經(jīng)理");
    }

    @Override
    public void reply(Worker worker) {
        System.out.println(getPosition() + "已通過(guò)你的請(qǐng)求");
    }}
/**
 * 總經(jīng)理處理類
 */
public class GeneralManager extends Leader {

    public GeneralManager(int hoildayNum) {
        super(hoildayNum);
        setPosition("總經(jīng)理");
    }

    @Override
    public void reply(Worker worker) {
        System.out.println(getPosition() + "已通過(guò)請(qǐng)求");
    }
}
public class Cilent {
    public static void main(String[] args) {
        Worker worker = new Worker(6);

        Leader projectDir = new ProjectDirector(1);
        Leader departmentMan = new DepartmentManager(3);
        Leader generalMan = new GeneralManager(10);
        projectDir.setSuccessor(departmentMan);
        departmentMan.setSuccessor(generalMan);

        projectDir.handleRequest(worker);
    }
}

這樣我們就把請(qǐng)求者與處理者優(yōu)雅的解耦餐弱。

純與不純的責(zé)任鏈模式

很多資料中會(huì)介紹純和不純的責(zé)任鏈模式宴霸,在標(biāo)準(zhǔn)的責(zé)任鏈模式中,責(zé)任鏈上的一個(gè)節(jié)點(diǎn)只允許有兩個(gè)行為:處理或者推給下個(gè)節(jié)點(diǎn)處理膏蚓,而不允許處理完之后又推給下個(gè)節(jié)點(diǎn)瓢谢,前者被很多資料稱為純的責(zé)任鏈模式,而后者被稱為不純的責(zé)任鏈模式驮瞧。其實(shí)在實(shí)際的系統(tǒng)里氓扛,純的責(zé)任鏈很難找到。如果堅(jiān)持責(zé)任鏈不純便不是責(zé)任鏈模式论笔,那么責(zé)任鏈模式便不會(huì)有太大意義了采郎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末千所,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蒜埋,更是在濱河造成了極大的恐慌淫痰,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件理茎,死亡現(xiàn)場(chǎng)離奇詭異黑界,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)皂林,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)朗鸠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人础倍,你說(shuō)我怎么就攤上這事烛占。” “怎么了沟启?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵忆家,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我德迹,道長(zhǎng)芽卿,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任胳搞,我火速辦了婚禮卸例,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肌毅。我一直安慰自己筷转,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布悬而。 她就那樣靜靜地躺著呜舒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪笨奠。 梳的紋絲不亂的頭發(fā)上袭蝗,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音般婆,去河邊找鬼呻袭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腺兴,可吹牛的內(nèi)容都是我干的左电。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篓足!你這毒婦竟也來(lái)了段誊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤栈拖,失蹤者是張志新(化名)和其女友劉穎连舍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體涩哟,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡索赏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贴彼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潜腻。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖器仗,靈堂內(nèi)的尸體忽然破棺而出融涣,到底是詐尸還是另有隱情,我是刑警寧澤精钮,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布威鹿,位于F島的核電站,受9級(jí)特大地震影響轨香,放射性物質(zhì)發(fā)生泄漏忽你。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一臂容、第九天 我趴在偏房一處隱蔽的房頂上張望檀夹。 院中可真熱鬧,春花似錦策橘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至买决,卻和暖如春沛婴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背督赤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工嘁灯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躲舌。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓丑婿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羹奉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • 1 場(chǎng)景問(wèn)題# 1.1 申請(qǐng)聚餐費(fèi)用## 來(lái)考慮這樣一個(gè)功能:申請(qǐng)聚餐費(fèi)用的管理秒旋。 很多公司都有這樣的福利,就是項(xiàng)...
    七寸知架構(gòu)閱讀 3,134評(píng)論 3 58
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理诀拭,服務(wù)發(fā)現(xiàn)迁筛,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品耕挨,去做同樣的事情细卧,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 7,763評(píng)論 2 17
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法筒占,類相關(guān)的語(yǔ)法贪庙,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法赋铝,異常的語(yǔ)法插勤,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,634評(píng)論 18 399
  • #幸福是需要修出來(lái)的~每天進(jìn)步1%~幸福實(shí)修08班~8唐潔-富陽(yáng)# 20170903(77/99) 【幸福三朵玫瑰...
    你謝謝閱讀 171評(píng)論 1 4