使程式設計更有靈活性——責任鏈模式
《Android原始碼設計模式解析與實戰》讀書筆記(九)
《Android原始碼設計模式解析與實戰》PDF資料下載一、責任鏈模式簡介
責任鏈模式,是行為型設計模式之一。將多個節點首尾相連構成的模型稱為鏈。
對於鏈式結構,每個節點都可以被拆開再連線,因此鏈式結構也具有很好的靈活性。
1.1、定義
使很多物件都有機會處理請求,從而避免了請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,只要有物件處理它為止。
1.2、使用場景
- 多個物件可以處理同一請求,但具體由哪個物件處理則在執行時動態決定;
- 在請求處理者不明確的情況下向多個物件中的一個提交一個請求;
- 需要動態指定一組物件處理請求。
二、責任鏈模式的簡單實現
//抽象領導者 public abstract class Leader { protected Leader nextHandler;//上一級領導處理者 /** * 處理報賬請求 * @param money */ public final void handleRequest(int money) { if (money <= limit()) { handle(money); } else { if (null != nextHandler) { nextHandler.handleRequest(money); } } } /** * 自身能批覆的額度許可權 * @return */ public abstract int limit(); /** * 處理報賬行為 * @param money */ public abstract void handle(int money); }
public class GroupLeader extends Leader { @Override public int limit() { return 1000; } @Override public void handle(int money) { System.out.println("組長批覆報銷"+money+"元"); } }
public class Director extends Leader { @Override public int limit() { return 5000; } @Override public void handle(int money) { System.out.println("主管批覆報銷"+money+"元"); } }
public class Manager extends Leader { @Override public int limit() { return 10000; } @Override public void handle(int money) { System.out.println("經理批覆報銷"+money+"元"); } }
public class Boss extends Leader { @Override public int limit() { return Integer.MAX_VALUE; } @Override public void handle(int money) { System.out.println("老闆批覆報銷"+money+"元"); } }
//構造各個領導物件 GroupLeader groupLeader = new GroupLeader(); Director director = new Director(); Manager manager = new Manager(); Boss boss = new Boss(); //設定上一級領導處理者物件 groupLeader.nextHandler = director; director.nextHandler = manager; manager.nextHandler = boss; //發起報賬申請 groupLeader.handleRequest(50000);
對於責任鏈中的一個處理者物件,其只有兩個行為,一是處理請求,二是將請求轉送給下一個節點,不允許某個處理者物件在處理了請求後又將請求轉送給上一個節點的情況。
對於一條責任鏈來說,一個請求最終只有兩種情況,一是被某個處理物件所處理,另一個是所有物件均未對其處理,對於前一種情況稱該責任鏈為純的責任鏈,對於後一種情況稱為不純的責任鏈,在實際應用中,所見到的責任鏈模式大多為不純的責任鏈。
三、責任鏈模式實戰
public class FirstReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等於1000,則處理,否則繼續轉發給下一個Receiver if (limit == 1000) { //獲取Intent中附加的字串訊息並Toast String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //新增資訊傳送給下一個Receiver Bundle b = new Bundle(); b.putString("new","Message from FirstBroadcast"); setResultExtras(b); } } }
public class SecondReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等於100,則處理,否則繼續轉發給下一個Receiver if (limit == 100) { //獲取Intent中附加的字串訊息 String msg = intent.getStringExtra("msg"); //獲取上一個Receiver增加的訊息 Bundle b = getResultExtras(true); String str = b.getString("new"); //Toast Toast.makeText(context, msg+"-----"+str, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //新增資訊傳送給下一個Receiver Bundle b = new Bundle(); b.putString("new","Message from SecondReceiver"); setResultExtras(b); } } }
public class ThirdReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等於10,則處理,否則繼續轉發給下一個Receiver if (limit == 10) { //獲取Intent中附加的字串訊息 String msg = intent.getStringExtra("msg"); //獲取上一個Receiver增加的訊息 Bundle b = getResultExtras(true); String str = b.getString("new"); //Toast Toast.makeText(context, msg+"-----"+str, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //新增資訊傳送給下一個Receiver Bundle b = new Bundle(); b.putString("new","Message from ThirdReceiver"); setResultExtras(b); } } }
<receiver android:name=".FirstReceiver"> <intent-filter android:priority="1000"> <action android:name="com.gimiii.myfirstapp.action.ORDER_BROADCAST"/> </intent-filter> </receiver> <receiver android:name=".SecondReceiver"> <intent-filter android:priority="100"> <action android:name="com.gimiii.myfirstapp.action.ORDER_BROADCAST"/> </intent-filter> </receiver> <receiver android:name=".ThirdReceiver"> <intent-filter android:priority="10"> <action android:name="com.gimiii.myfirstapp.action.ORDER_BROADCAST"/> </intent-filter> </receiver>
Intent i = new Intent(); i.setAction("com.gimiii.myfirstapp.action.ORDER_BROADCAST"); i.putExtra("limit", 100); i.putExtra("msg", "Message from OrderActivity"); sendOrderedBroadcast(i, null);
將limit設定為100,只有SecondReceiver才會處理它。
四、總結
4.1、優點
可以對請求者和處理者關係解耦,提高程式碼的靈活性。
4.2、缺點
對鏈中請求處理者的遍歷,如果處理者太多那麼遍歷必定會影響效能。
學海無涯苦作舟

我的微信公眾號