Android編程設(shè)計(jì)模式之責(zé)任鏈模式詳解
本文實(shí)例講述了Android編程設(shè)計(jì)模式之責(zé)任鏈模式。分享給大家供大家參考,具體如下:
一、介紹
責(zé)任鏈模式(Iterator Pattern),是行為型設(shè)計(jì)模式之一。什么是”鏈“?我們將多個(gè)節(jié)點(diǎn)首尾相連所構(gòu)成的模型稱為鏈,比如生活中常見的鎖鏈,就是由一個(gè)個(gè)圓角長(zhǎng)方形的鐵環(huán)串起來的結(jié)構(gòu)。對(duì)于鏈?zhǔn)浇Y(jié)構(gòu),每個(gè)節(jié)點(diǎn)都可以被拆開再連接,因此,鏈?zhǔn)浇Y(jié)構(gòu)也具有很好的靈活性。將這樣一種結(jié)構(gòu)應(yīng)用于編程領(lǐng)域,將每一個(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é)任鏈模式,這樣的解釋是不是更通俗易懂呢?我們還是看看責(zé)任鏈模式的標(biāo)準(zhǔn)定義。
二、定義
使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者直接的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞請(qǐng)求,直到有對(duì)象處理它為止。
三、使用場(chǎng)景
多個(gè)對(duì)象可以處理同一請(qǐng)求,但具體由哪個(gè)對(duì)象處理則在運(yùn)行時(shí)動(dòng)態(tài)決定。
在請(qǐng)求處理者不明確的情況下向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。
需要?jiǎng)討B(tài)指定一組對(duì)象處理請(qǐng)求。
四、責(zé)任鏈模式的UML類圖
UML類圖:
角色介紹:
Handler:抽象處理者角色,聲明一個(gè)請(qǐng)求處理的方法,并在其中保持一個(gè)對(duì)下一個(gè)處理節(jié)點(diǎn)Handler對(duì)象的引用。
ConcreteHandler:具體處理者角色,對(duì)請(qǐng)求進(jìn)行處理,如果不能處理則將該請(qǐng)求轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn)上的處理對(duì)象。
五、簡(jiǎn)單實(shí)現(xiàn)
這個(gè)例子我覺得很貼切。我們?cè)诠居懈鞣N原因需要報(bào)銷費(fèi)用,首先我們要找我們的上級(jí)領(lǐng)導(dǎo)去審批,報(bào)銷額度如果在領(lǐng)導(dǎo)的權(quán)限范圍內(nèi),那就審批通過,否則領(lǐng)導(dǎo)在找自己的上級(jí)去審批,以此類推。
抽象領(lǐng)導(dǎo)類:
public abstract class Leader { /** * 上級(jí)領(lǐng)導(dǎo)處理者 */ protected Leader nextHandler; /** * 處理報(bào)賬請(qǐng)求 * * @param money 能批復(fù)的報(bào)賬額度 * */ public final void handleRequest(int money){ System.out.println(getLeader()); if(money <=limit()){ handle(money); }else{ System.out.println("報(bào)賬額度不足,提交領(lǐng)導(dǎo)"); if(null != nextHandler){ nextHandler.handleRequest(money); } } } /** * 自身能批復(fù)的額度權(quán)限 * * @return 額度 */ public abstract int limit(); /** * 處理報(bào)賬行為 * * @param money 具體金額 */ public abstract void handle(int money); /** * 獲取處理者 * * @return 處理者 */ public abstract String getLeader(); }
在這個(gè)抽象的領(lǐng)導(dǎo)類中只做了兩件事,一是定義了兩個(gè)抽象接口方法來確定一個(gè)領(lǐng)導(dǎo)者應(yīng)有的行為和屬性,二是聲明了一個(gè)處理報(bào)賬請(qǐng)求的方法來確定當(dāng)前領(lǐng)導(dǎo)是否有能力處理報(bào)賬請(qǐng)求,如果沒有這個(gè)權(quán)限,則將該請(qǐng)求轉(zhuǎn)發(fā)給上級(jí)領(lǐng)導(dǎo)處理。接下來則是各個(gè)領(lǐng)導(dǎo)類的實(shí)現(xiàn):
組長(zhǎng)(額度1000):
public class GroupLeader extends Leader{ @Override public int limit() { return 1000; } @Override public void handle(int money) { System.out.println("組長(zhǎng)批復(fù)報(bào)銷"+ money +"元"); } @Override public String getLeader() { return "當(dāng)前是組長(zhǎng)"; } }
主管(額度5000):
public class Director extends Leader{ @Override public int limit() { return 5000; } @Override public void handle(int money) { System.out.println("主管批復(fù)報(bào)銷"+ money +"元"); } @Override public String getLeader() { return "當(dāng)前是主管"; } }
經(jīng)理(額度10000):
public class Manager extends Leader{ @Override public int limit() { return 10000; } @Override public void handle(int money) { System.out.println("經(jīng)理批復(fù)報(bào)銷"+ money +"元"); } @Override public String getLeader() { return "當(dāng)前是經(jīng)理"; } }
老板(額度…):
public class Boss extends Leader{ @Override public int limit() { return Integer.MAX_VALUE; } @Override public void handle(int money) { System.out.println("老板批復(fù)報(bào)銷"+ money +"元"); } @Override public String getLeader() { return "當(dāng)前是老板"; } }
發(fā)起申請(qǐng):
public class Client { public static void main(String[] args) { //構(gòu)造各個(gè)領(lǐng)導(dǎo)對(duì)象 GroupLeader groupLeader = new GroupLeader(); Director director = new Director(); Manager manager = new Manager(); Boss boss = new Boss(); //設(shè)置上級(jí)領(lǐng)導(dǎo)處理者對(duì)象 groupLeader.nextHandler = director; director.nextHandler = manager; manager.nextHandler = boss; //發(fā)起報(bào)賬申請(qǐng) groupLeader.handleRequest(8000); } }
結(jié)果:
當(dāng)前是組長(zhǎng) 報(bào)賬額度不足,提交領(lǐng)導(dǎo) 當(dāng)前是主管 報(bào)賬額度不足,提交領(lǐng)導(dǎo) 當(dāng)前是經(jīng)理 經(jīng)理批復(fù)報(bào)銷8000元
責(zé)任鏈模式非常靈活,請(qǐng)求的發(fā)起可以從責(zé)任鏈的任何一個(gè)節(jié)點(diǎn)開始,也可以改變內(nèi)部的傳遞規(guī)則。比如主管不在,我們完全可以跨過主管直接從組長(zhǎng)那里轉(zhuǎn)到經(jīng)理。
對(duì)于責(zé)任鏈中的一個(gè)處理者對(duì)象,有兩個(gè)行為。一是處理請(qǐng)求,二是將請(qǐng)求傳遞到下一節(jié)點(diǎn),不允許某個(gè)處理者對(duì)象在處理了請(qǐng)求后又將請(qǐng)求傳送給上一個(gè)節(jié)點(diǎn)的情況。
對(duì)于一條責(zé)任鏈來說,一個(gè)請(qǐng)求最終只有兩種情況。一是被某個(gè)處理對(duì)象所處理,另一個(gè)是所有對(duì)象均未對(duì)其處理,對(duì)于前一種情況我們稱為純的責(zé)任鏈模式,后一種為不純的責(zé)任鏈。實(shí)際中大多為不純的責(zé)任鏈。
六、Android源碼中的責(zé)任鏈模式
1、View事件的分發(fā)處理
ViewGroup事件投遞的遞歸調(diào)用就類似于一條責(zé)任鏈,一旦其尋找到責(zé)任者,那么將由責(zé)任者持有并消費(fèi)掉該次事件,具體體現(xiàn)在View的onTouchEvent方法中返回值的設(shè)置,如果返回false,那么意味著當(dāng)前的View不會(huì)是該次的責(zé)任人,將不會(huì)對(duì)其持有;如果返回true,此時(shí)View會(huì)持有該事件并不再向外傳遞。
七、總結(jié)
優(yōu)點(diǎn):
可以對(duì)請(qǐng)求者和處理者的關(guān)系解耦,提高代碼的靈活性。
缺點(diǎn):
每次都需要對(duì)鏈中請(qǐng)求處理者遍歷,如果處理者太多那么遍歷必定會(huì)影響性能,特別是在一些遞歸調(diào)用者中,要慎用。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android編程設(shè)計(jì)模式之訪問者模式詳解
- Android編程設(shè)計(jì)模式之模板方法模式詳解
- Android編程設(shè)計(jì)模式之迭代器模式詳解
- Android編程設(shè)計(jì)模式之備忘錄模式詳解
- Android編程設(shè)計(jì)模式之命令模式詳解
- Android編程設(shè)計(jì)模式之解釋器模式詳解
- Android編程設(shè)計(jì)模式之狀態(tài)模式詳解
- Android編程設(shè)計(jì)模式之策略模式詳解
- Android編程設(shè)計(jì)模式之抽象工廠模式詳解
- android設(shè)計(jì)模式之單例模式詳解
- Android編程設(shè)計(jì)模式之中介者模式詳解
相關(guān)文章
簡(jiǎn)單掌握Android Widget桌面小部件的創(chuàng)建步驟
這篇文章主要介紹了簡(jiǎn)單掌握Android Widget桌面小部件的創(chuàng)建步驟,Widget一般采用web前端技術(shù)進(jìn)行開發(fā),需要的朋友可以參考下2016-03-03android中Bitmap用法(顯示,保存,縮放,旋轉(zhuǎn))實(shí)例分析
這篇文章主要介紹了android中Bitmap用法,以實(shí)例形式較為詳細(xì)的分析了android中Bitmap操作圖片的顯示、保存、縮放、旋轉(zhuǎn)等相關(guān)技巧,需要的朋友可以參考下2015-09-09Jetpack?Compose重寫TopAppBar實(shí)現(xiàn)標(biāo)題多行折疊詳解
這篇文章主要為大家介紹了Jetpack?Compose重寫TopAppBar實(shí)現(xiàn)標(biāo)題多行折疊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Flutter使用RepositoryProvider解決跨組件傳值問題
在實(shí)際開發(fā)過程中,經(jīng)常會(huì)遇到父子組件傳值的情況。本文將利用RepositoryProvider解決跨組件傳值的問題,感興趣的小伙伴可以了解一下2022-04-04Android使用AlarmManager設(shè)置鬧鐘功能
這篇文章主要為大家詳細(xì)介紹了Android使用AlarmManager設(shè)置鬧鐘功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09Android使用ViewPager完成app引導(dǎo)頁(yè)
這篇文章主要為大家詳細(xì)介紹了Android使用ViewPager完成app引導(dǎo)頁(yè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11Android 6.0權(quán)限請(qǐng)求相關(guān)及權(quán)限分組方法
今天小編就為大家分享一篇Android 6.0權(quán)限請(qǐng)求相關(guān)及權(quán)限分組方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08