1、概念
是一個請求有多個對象來處理,這些對象是一條鏈,但具體由哪個對象來處理,根據條件判斷來確定,如果不能處理會傳遞給該鏈中的下一個對象,直到有對象處理它爲止。
2、使用場景
- 有多個對象可以處理同一個請求,具體哪個對象處理該請求待運行時刻再確定
- 在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
- 可動態制定一組對象處理請求,客戶端可以動態創建職責鏈來處理請求。
3、uml結構分析
4、實際代碼分析
/**
* 抽象請假審批類
*/
public abstract class Handler {
public int maxDay;
private Handler nextHandler;
public Handler(int maxDay) {
this.maxDay = maxDay;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public void handlerRequest(int day){
if(day <= maxDay){
reply(day);
} else{
if(nextHandler != null){
nextHandler.handlerRequest(day);
}else {
System.out.println("沒有跟高的領導審批了");
}
}
}
protected abstract void reply(int day);
}
/**
* 技術主管審批類
*/
public class Handler1 extends Handler {
public Handler1() {
super(10);
}
@Override
protected void reply(int day) {
System.out.print(day+"天請假,技術主管直接通過");
}
}
* 項目經理審批類
*/
public class Handler2 extends Handler {
public Handler2() {
super(5);
}
@Override
protected void reply(int day) {
System.out.print(day+"天請假,項目經歷直接通過");
}
}
//代碼運行
Handler2 handler2 = new Handler2();
handler2.setNextHandler(new Handler1());
handler2.handlerRequest(3);
在java中的實際運用,try-cache語句
在android 中發佈有序廣播 ordered broadcast,viewGroup/view 事件傳遞
優點與缺點
責任鏈模式是一種對象行爲型模式,其主要優點如下。
- 降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。
- 增強了系統的可擴展性。可以根據需要增加新的請求處理類,滿足開閉原則。
- 增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。
- 責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其後繼者的引用,不需保持其他所有處理者的引用,這避免了使用衆多的 if 或者 if···else 語句。
- 責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任範圍,符合類的單一職責原則。
其主要缺點如下。
- 不能保證每個請求一定被處理。由於一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
- 對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。
- 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的複雜性,可能會由於職責鏈的錯誤設置而導致系統出錯,如可能會造成循環調用。
viewGroup/view 事件傳遞
1)主要概念
MotionEvent 事件分發的基本操作,所有事件都是MotionEvent,對MotionEvent操作。
主要有三種操作 ACTION_DOWN/ACTION_MOVE/ACTION_UP
三個方法
dispatchTouchEvent 當有事件傳遞給view的時候,view就會調用該方法。這個返回值爲boolean,返回告訴系統是否消耗了該事件。true爲消耗,不會繼續向下分發
onIntereptTouchEvent 攔截事件,只存在於viewgroup,view(存在於view樹的最底層,沒必要攔截了)中沒有攔截事件。如果當前view 成功攔截這個事件,則要返回true,默認爲false
onTouchEvent 具體處理整個事件邏輯的,對於他的返回結果就是是否消耗當前事件,如果不消耗當前事件的話,對於同一個事件,當前view就不會再接到這個事件。
總結:如果當前view可以處理就攔截處理,如果不可以,就交給子view
事件處理順序
Activity -> PhoneWindow ->RootView ->ViewGroup ->View
2)viewgroup的事件分發
流程:
- 判斷自身是否需要
- 自身不需要或者不確定,詢問childview
- 如果子childview 不需要則調用自身的onTouchEvent
3)view的事件分發
view爲啥會有dispatchTouchEvent方法?view可以註冊很多事件監聽器,可以進行事件分發
- 單機事件(onClickListener)
- 長按事件(onLongClickListener)
- 觸摸事件(onTouchListener)
- View自身處理(onTouchEvent)
事件調用順序:onTouchListener>onTouchEvent>onLongClickListener>onClickListener