Android 設計模式 - 責任鏈模式
什麼時候使用責任鏈模式
當處理一個事件是根據這個事件的某個條件去決定哪個處理物件的時候可以考慮使用責任鏈模式.

具體我們從一個程式碼示範入手,定義一個抽象的處理者
public abstract class AbstractHandler { public AbstractHandler nextHandler; /** * 處理請求,當Request Level 和 Handle Level相等就表明該請求交由該處理者處理 */ public final void handleRequest(AbstractRequest request){ if (getHandleLevel() == request.getRequestLevel()){ handle(request); }else { if (nextHandler != null){ nextHandler.handle(request); } else{ System.out.println("All of handler can not handle the request"); } } } /** * 獲取處理物件的處理級別 * @return */ protected abstract int getHandleLevel(); /** * 每個處理物件的具體處理方式 */ protected abstract void handle(AbstractRequest request); }
再定義一個抽象的請求
public abstract class AbstractRequest { private Object obj; public AbstractRequest(Object obj) { this.obj = obj; } /** * 獲取處理內容的物件 */ public Object getContent(){ return obj; } /** * 獲取請求級別 */ public abstract int getRequestLevel(); }
下面分別定義3個實際的處理者和3個實際的請求
public class Handler1 extends AbstractHandler{ @Override protected int getHandleLevel() { return 1; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler1 handle request : "+request.getRequestLevel()); } }
public class Handler2 extends AbstractHandler{ @Override protected int getHandleLevel() { return 2; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler2 handle request : "+request.getRequestLevel()); } }
public class Handler3 extends AbstractHandler{ @Override protected int getHandleLevel() { return 3; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler3 handle request : "+request.getRequestLevel()); } }
public class Request1 extends AbstractRequest{ public Request1(Object obj) { super(obj); } @Override public int getRequestLevel() { return 1; } }
public class Request2 extends AbstractRequest{ public Request2(Object obj) { super(obj); } @Override public int getRequestLevel() { return 2; } }
public class Request3 extends AbstractRequest{ public Request3(Object obj) { super(obj); } @Override public int getRequestLevel() { return 3; } }
最終呼叫
Handler1 handler1 = new Handler1(); Handler2 handler2 = new Handler2(); Handler3 handler3 = new Handler3(); /** * 構建責任鏈 */ handler1.nextHandler = handler2; handler2.nextHandler = handler3; Request1 request1 = new Request1("request 1"); Request2 request2 = new Request2("request 2"); Request3 request3 = new Request3("request 3"); handler1.handleRequest(request1); handler1.handleRequest(request2); handler3.handleRequest(request3);
輸出:
01-13 21:33:44.684 22261-22261/? I/System.out: Handler1 handle request : 1 01-13 21:33:44.684 22261-22261/? I/System.out: Handler2 handle request : 2 01-13 21:33:44.684 22261-22261/? I/System.out: Handler3 handle request : 3
上面我們建立Request並交給Handler構建的一條責任鏈處理,當滿足Request的Level和Handler的Level相等的情況就交由該Handler進行處理,這就是一個責任鏈的基本實現.
下面在再舉一個實際栗子看看運用上面這套責任鏈模式程式碼.
目前小明出國出差回來,出差的經費是50000元,小明需要報銷這筆經費,他首先找到他的組長處理報銷問題,但是組長這邊只能處理1000元以下的報銷,組長表示找上面的部門主管批覆,於是找到部門主管,部門主管只能處理5000以下的報銷,於是部門主管找到經理批覆,經理只能處理10000元以下的報銷,於是經理找到老闆,進行報銷批覆。處理報銷經費事件這一連串人可以看作是一個責任鏈,我們可以用責任鏈模式去實現上面的需求.
先抽象領導
public abstract class Leader { //上級領導 public Leader nextHandler; 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 */ protected abstract void handle(int money); }
具體的四個領導
public class GroupLeader extends Leader{ @Override public int limit() { return 1000; } @Override protected void handle(int money) { System.out.println("組長批覆報銷 "+money+" 元"); } } public class Director extends Leader{ @Override public int limit() { return 5000; } @Override protected void handle(int money) { System.out.println("主管批覆報銷 "+money+"元"); } } public class Manager extends Leader{ @Override public int limit() { return 10000; } @Override protected void handle(int money) { System.out.println("經理批覆報銷 "+money+"元"); } } public class Boss extends Leader{ @Override public int limit() { return Integer.MAX_VALUE; } @Override protected 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);
輸出
01-13 21:48:40.181 22459-22459/? I/System.out: 老闆批覆報銷50000元
其實責任鏈模式也並不是一定要按照上面那套模版程式碼去實現,關鍵是要突出處理一個事件的處理者再不滿足處理該事件條件的情況下把事件傳遞給下一個處理者這種思想. 最後再來一個栗子,在Android開發中廣播分為兩種,一種是Normal Broadcast另外一種是Order Broadcast, 傳送Normal Broadcast是所有註冊該廣播的廣播接收者都能接收到。Order Broadcast是按照廣播接收者優先順序依次傳送,接收到該廣播的廣播接收者可以選擇是否繼續向下傳遞,我們可以利用Order Broadcast這樣的機制來實現一條責任鏈.
public class FirstBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { int limit = intent.getIntExtra("limit",-1001); if (limit == 1000){ String msg = intent.getStringExtra("msg"); Toast.makeText(context,msg,Toast.LENGTH_SHORT).show(); abortBroadcast(); } else { Bundle b = new Bundle(); b.putString("new","Message from FirstReceiver"); setResultExtras(b); } } }
public class SecondBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { int limit = intent.getIntExtra("limit",-1001); if (limit == 100){ String msg = intent.getStringExtra("msg"); //取上一個receiver的附加資訊 Bundle b = getResultExtras(true); String str = b.getString("new"); Toast.makeText(context,msg+" ----- "+str,Toast.LENGTH_SHORT).show(); abortBroadcast(); }else{ Bundle b = new Bundle(); b.putString("new","Message from SecondReceiver"); setResultExtras(b); } } }
public class ThirdBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { int limit = intent.getIntExtra("limit",-1001); if (limit == 10){ String msg = intent.getStringExtra("msg"); Bundle b = getResultExtras(true); String str = b.getString("new"); Toast.makeText(context,msg+" ---- "+str,Toast.LENGTH_SHORT).show(); abortBroadcast(); }else{ Bundle b = new Bundle(); b.putString("new","Message from ThirdReceiver"); setResultExtras(b); } } }
在AndroidManifest.xml中申明這3個Receiver,並設定對應的許可權值.
<receiver android:name=".broadcast.FirstBroadcastReceiver"> <intent-filter android:priority="1000" > <action android:name="com.example.huangli.action.ORDER_BROADCAST"></action> </intent-filter> </receiver> <receiver android:name=".broadcast.SecondBroadcastReceiver"> <intent-filter android:priority="100" > <action android:name="com.example.huangli.action.ORDER_BROADCAST"></action> </intent-filter> </receiver> <receiver android:name=".broadcast.ThirdBroadcastReceiver"> <intent-filter android:priority="10" > <action android:name="com.example.huangli.action.ORDER_BROADCAST"></action> </intent-filter> </receiver>
最後呼叫:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendBroadcast(); } private void sendBroadcast() { Intent intent = new Intent(); intent.setAction("com.example.huangli.action.ORDER_BROADCAST"); intent.putExtra("limit", 100); intent.putExtra("msg", "Message from MainActivity"); sendOrderedBroadcast(intent, null); } }
我們將limit設定成了100,它會在SecondBroadcastReceiver進行處理,實際效果大家可以試試。
【附錄】

資料圖
需要資料的朋友可以加入Android架構交流QQ群聊:513088520
點選連結加入群聊【Android移動架構總群】: 加入群聊
獲取免費學習視訊,學習大綱另外還有像高階UI、效能優化、架構師課程、NDK、混合式開發(ReactNative+Weex)等Android高階開發資料免費分享。