介紹
它是一種行為型設(shè)計(jì)模式之一。它的每一個(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é)任鏈模式。
使用場(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)求。
示例一
說明:此為簡(jiǎn)化版代碼,分為抽象處理者,具體的處理者。代碼如下:
-
抽象處理者
public abstract class Handler { protected Handler successor; //下一節(jié)點(diǎn)的處理者 /** * 請(qǐng)求處理 * @param condition 請(qǐng)求條件 */ public abstract void handleRequest(String condition); } -
具體的處理者1
public class ConcreteHandler1 extends Handler { @Override public void handleRequest(String condition) { if (condition.equals("ConcreteHandler1")) { System.out.println("ConcreteHandler1 handled"); } else { successor.handleRequest(condition); } } } -
具體的處理者2
public class ConcreteHandler2 extends Handler { @Override public void handleRequest(String condition) { if (condition.equals("ConcreteHandler2")) { System.out.println("ConcreteHandler2 handled"); } else { successor.handleRequest(condition); } } } -
客戶類
public class Client { public static void main(String[] args) { //構(gòu)造一個(gè)ConcreteHandler1對(duì)象 ConcreteHandler1 handler1 = new ConcreteHandler1(); //構(gòu)造一個(gè)ConcreteHandler2對(duì)象 ConcreteHandler2 handler2 = new ConcreteHandler2(); //設(shè)置handler1的下一個(gè)節(jié)點(diǎn) handler1.successor = handler2; //設(shè)置handler2的下一個(gè)節(jié)點(diǎn) handler2.successor = handler1; //處理請(qǐng)求 handler1.handleRequest("ConcreteHandler2"); } }
示例二
說明:抽象處理者,抽象請(qǐng)求者,請(qǐng)求者,處理者。代碼如下:
-
抽象處理者
public abstract class AbstractHandler { protected AbstractHandler nextHandler; //下一節(jié)點(diǎn)的處理者對(duì)象 /** * 請(qǐng)求處理 * @param request 請(qǐng)求條件 */ public final void handleRequest(AbstractRequest request) { //判斷當(dāng)前處理者對(duì)象的處理級(jí)別是否與請(qǐng)求者的處理級(jí)別一致 if (getHandleLevel() == request.getRequestLevel()) { //一致則由該處理對(duì)象處理 handle(request); } else { //否則將該請(qǐng)求對(duì)象轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn)上的請(qǐng)求對(duì)象 if (nextHandler != null) { nextHandler.handleRequest(request); } else { //所有處理者對(duì)象均不能處理該請(qǐng)求時(shí)輸出 System.out.println("All of handler can not handle the request"); } } } /** * 獲取處理者對(duì)象的處理級(jí)別 * @return 處理級(jí)別 */ protected abstract int getHandleLevel(); /** * 每個(gè)處理者對(duì)象的具體處理方式 * @param request 請(qǐng)求者對(duì)象 */ protected abstract void handle(AbstractRequest request); } -
抽象請(qǐng)求者
public abstract class AbstractRequest { private Object obj; //處理對(duì)象 public AbstractRequest(Object obj) { this.obj = obj; } public Object getContent() { return obj; } /** * 獲取請(qǐng)求級(jí)別 * @return 請(qǐng)求級(jí)別 */ public abstract int getRequestLevel(); } -
請(qǐng)求者
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; } } -
處理者
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 Client { public static void main(String[] args) { //構(gòu)造3個(gè)處理者對(duì)象 AbstractHandler handler1 = new Handler1(); AbstractHandler handler2 = new Handler2(); AbstractHandler handler3 = new Handler3(); //設(shè)置當(dāng)前處理者對(duì)象下一個(gè)節(jié)點(diǎn)的處理者對(duì)象 handler1.nextHandler = handler2; handler2.nextHandler = handler3; //構(gòu)造3個(gè)請(qǐng)求者對(duì)象 AbstractRequest request1 = new Request1("Request1"); AbstractRequest request2 = new Request2("Request2"); AbstractRequest request3 = new Request3("Request3"); //總是從鏈?zhǔn)降氖锥税l(fā)起請(qǐng)求 handler1.handleRequest(request1); handler1.handleRequest(request2); handler1.handleRequest(request3); } }
示例三
說明:小明出差學(xué)些新技術(shù),其中花費(fèi)了5w元,于是小明去找組長報(bào)銷費(fèi)用。。。代碼如下:
-
抽象領(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) { if (money <= limit()) { handle(money); } else { if (nextHandler != null) { nextHandler.handleRequest(money); } } } /** * 自身能夠批復(fù)的額度權(quán)限 * @return 額度 */ protected abstract int limit(); /** * 處理報(bào)賬行為 * @param money 具體金額 */ protected abstract void handle(int money); } -
具體的領(lǐng)導(dǎo)者
public class GroupLeader extends Leader { @Override protected int limit() { return 1000; } @Override protected void handle(int money) { System.out.println("組長批復(fù)報(bào)銷" + money + "元"); } }public class Director extends Leader { @Override protected int limit() { return 5000; } @Override protected void handle(int money) { System.out.println("主管批復(fù)報(bào)銷" + money + "元"); } }public class Manager extends Leader { @Override protected int limit() { return 10000; } @Override protected void handle(int money) { System.out.println("經(jīng)理批復(fù)報(bào)銷" + money + "元"); } }public class Boss extends Leader { @Override protected int limit() { return Integer.MAX_VALUE; } @Override protected void handle(int money) { System.out.println("老板批復(fù)報(bào)銷" + money + "元"); } } -
客戶類小明
public class XiaoMing { 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(50000); } }小明先找組長報(bào)賬,然后組長找到主管,主管找到經(jīng)理,經(jīng)理最后找到老板解決。
當(dāng)然也可以直接跳過某個(gè)人。
對(duì)于責(zé)任鏈中的一個(gè)處理者對(duì)象,其只有兩種行為,一是處理請(qǐng)求,二是將請(qǐng)求轉(zhuǎn)送給下一個(gè)節(jié)點(diǎn),不允許某個(gè)處理者對(duì)象在處理了請(qǐng)求后又將請(qǐng)求轉(zhuǎn)送給上一個(gè)節(jié)點(diǎn)的情況。
對(duì)于一條責(zé)任鏈來說,一個(gè)請(qǐng)求最終只有兩種情況,一個(gè)唄某個(gè)處理對(duì)象所處理,另一個(gè)是所有對(duì)象均未對(duì)其處理,對(duì)于前一種情況我們稱該責(zé)任鏈為純的責(zé)任鏈,對(duì)于后一種情況我們稱為不純的責(zé)任鏈,在實(shí)際應(yīng)用中,我們所見到的責(zé)任鏈模式大多為不純的責(zé)任鏈。
Android 源碼中的實(shí)現(xiàn)
事件的分發(fā)處理。
責(zé)任鏈模式實(shí)戰(zhàn)
說明:有序廣播的處理。源碼地址
-
廣播接收者
public class FirstReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等于1000,則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver if (limit == 1000) { //獲取Intent中附加的字符串消息并Toast String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //添加信息發(fā)送給下一個(gè)Receiver Bundle bundle = new Bundle(); bundle.putString("new", "Message from FirstReceiver"); setResultExtras(bundle); } } }public class SecondReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等于100,則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver if (limit == 100) { //獲取Intent中附加的字符串消息并Toast String msg = intent.getStringExtra("msg"); //獲取上一個(gè)Receiver增加的消息 Bundle bundle = getResultExtras(true); String str = bundle.getString("new"); Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //添加信息發(fā)送給下一個(gè)Receiver Bundle bundle = new Bundle(); bundle.putString("new", "Message from SecondReceiver"); setResultExtras(bundle); } } }public class ThirdReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取Intent中附加的限制值 int limit = intent.getIntExtra("limit", -1001); //如果限制值等于10,則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver if (limit == 10) { //獲取Intent中附加的字符串消息并Toast String msg = intent.getStringExtra("msg"); //獲取上一個(gè)Receiver增加的消息 Bundle bundle = getResultExtras(true); String str = bundle.getString("new"); Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show(); //終止廣播 abortBroadcast(); } else { //添加信息發(fā)送給下一個(gè)Receiver Bundle bundle = new Bundle(); bundle.putString("new", "Message from ThirdReceiver"); setResultExtras(bundle); } } } -
部分清單文件數(shù)據(jù)
<receiver android:name="com.yan.iterator.FirstReceiver"> <intent-filter android:priority="1000"> <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/> </intent-filter> </receiver> <receiver android:name="com.yan.iterator.SecondReceiver"> <intent-filter android:priority="100"> <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/> </intent-filter> </receiver> <receiver android:name="com.yan.iterator.ThirdReceiver"> <intent-filter android:priority="10"> <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/> </intent-filter> </receiver> -
MainActivity
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction("com.yan.iterator.action.ORDER_BROADCAST"); intent.putExtra("limit", 100); intent.putExtra("msg", "Message from MainActivity"); sendOrderedBroadcast(intent, null); } }); } }
總結(jié)
-
優(yōu)點(diǎn)
可以對(duì)請(qǐng)求者和處理者關(guān)系解耦,提高代碼的靈活性。
-
缺點(diǎn)
對(duì)鏈中請(qǐng)求處理者的遍歷,如果處理者太多,那么遍歷必定會(huì)影響性能,特別是在一些遞歸調(diào)用中,要慎重。