1.責(zé)任鏈模式的定義及使用場景
定義:
責(zé)任鏈模式是行為型設(shè)計模式之一迄薄。使多個對象都有機會處理請求在跳,從而避免了請求的發(fā)送者和接受者之間的耦合關(guān)系岁忘。將這些對象連成一條鏈舵稠,并沿著這條鏈傳遞該請求蠢壹,直到有對象處理它為止
使用場景:
使多個對象都有機會處理請求嗓违,從而避免了請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈图贸,并沿著這條鏈傳遞該請求蹂季,只到有對象處理它為止
2 . 責(zé)任鏈模式的優(yōu)缺點
2.1優(yōu)點
責(zé)任鏈模式非常顯著的優(yōu)點是將請求和處理分開。請求者可以不用知道是誰處理疏日,處理者可以不用知道請求的全貌偿洁,兩者解耦,提高系統(tǒng)的靈活性
2.2缺點
責(zé)任鏈有兩個非常顯著的缺點:一是性能問題沟优,每個請求都是從鏈頭遍歷到鏈尾涕滋,特別是在鏈比較長的時候,性能是一個比較大的問題挠阁;二是調(diào)試不很方便宾肺,特別是鏈條比較長溯饵,環(huán)節(jié)比較多的時候,由于采用了類似遞歸的方式锨用,調(diào)試的時候邏輯可能比較復(fù)雜
3.注意實現(xiàn)
鏈中節(jié)點數(shù)量需要控制丰刊,避免出現(xiàn)超長鏈的情況,一般的做法是在handler中設(shè)置一個最大節(jié)點數(shù)量增拥,在setNext方法中判斷是否已經(jīng)是超過其閾值啄巧,超過則不允許該鏈建立,避免無意識地破壞系統(tǒng)性能
4. 責(zé)任鏈模式的實現(xiàn)方式
public abstract class AbstractRequest {
private Object obj;//處理對象
public AbstractRequest(Object object) {
this.obj = object;
}
public Object getContent() {
return obj;
}
//獲取請求的級別
public abstract int getRequestLevel();
}```
public abstract class AbstractHandler {
protected AbstractHandler nexthandler;//下一節(jié)點處理對象
public final void handleRequest(AbstractRequest request) {
if(getHandleLevel()==request.getRequestLevel()){
handle(request);
}else{
if(nexthandler!=null){
nexthandler.handleRequest(request);
}else{
System.out.println("All of handler can not handle the request");
}
}
}
//獲取處理者對象的處理級別
protected abstract int getHandleLevel();
//每個處理者對象的具體處理方式
protected abstract void handle(AbstractRequest request);
}```
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 object) {
super(object);
}
@Override
public int getRequestLevel() {
return 1;
}
}```
public class Request2 extends AbstractRequest {
public Request2(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 2;
}
}```
public class Request3 extends AbstractRequest {
public Request3(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 3;
}
}```
public class Request4 extends AbstractRequest {
public Request4(Object object) {
super(object);
}
@Override
public int getRequestLevel() {
return 4;
}
}```
public class Test {
public static void main(String args[]) {
AbstractHandler h1=new Handler1();
AbstractHandler h2=new Handler2();
AbstractHandler h3=new Handler3();
h1.nexthandler=h2;
h2.nexthandler=h3;
AbstractRequest r1=new Request1(h1);
AbstractRequest r2=new Request2(h2);
AbstractRequest r3=new Request3(h3);
AbstractRequest r4=new Request4(h3);
//總是從鏈?zhǔn)降氖锥税l(fā)起請求
h1.handleRequest(r1);
h1.handleRequest(r2);
h1.handleRequest(r3);
h1.handleRequest(r4);
}
}```
5. 責(zé)任鏈模式在Android中的實際應(yīng)用
責(zé)任鏈模式在Android源碼中比較類似的實現(xiàn)就是對于觸摸事件的分發(fā)處理跪者。每當(dāng)用戶接觸屏幕時棵帽,Android都會將對應(yīng)的事件包裝成一個事件對象從ViewTree的頂部至上而下地分發(fā)傳遞熄求。ViewGroup事件投遞的遞歸調(diào)用就類似于一條責(zé)任鏈渣玲,一旦尋找到責(zé)任者,那么將由責(zé)任者持有并消費掉該次事件弟晚,具體地體現(xiàn)在View的onTouchEvent方法中返回值的設(shè)置忘衍,如果onTouchEvent返回false,那么意味著當(dāng)前View不會是該次事件的復(fù)制人卿城,將不會對其持有枚钓;如果為true則相反,此時View會持有該事件并不再向外傳遞瑟押。
View的事件分發(fā)機制(MontionEvent的分發(fā)過程):
public boolean dispatchTouchEvent(MotionEvent ev)
如果事件能夠傳遞到當(dāng)前的View搀捷,那么此方法一定會被調(diào)用。
public boolean onInterceptTouchEvent(MotionEvent ev)
用來判斷是否攔截某個事件
public boolean onTouchEvent(MotionEvent ev)
用來處理點擊事件
流轉(zhuǎn)關(guān)系(偽代碼)
public boolean dispatchTouchEvent(MotionEvent ev){
boolean consume=false;
if(onInterceptTouchEvent(ev)){
consume=onTouchEvent(ev);
}else{
consume=child.dispatchTouchEvent(ev);
}
return consume;
}```
出處:http://huangjunbin.com/page/2/