1、 責(zé)任鏈模式概念
1.1 介紹
客戶端發(fā)出一個(gè)請(qǐng)求,鏈上的對(duì)象都有機(jī)會(huì)來(lái)處理這一請(qǐng)求书蚪,而客戶端不需要知道誰(shuí)是具體的處理對(duì)象竹海。這樣就實(shí)現(xiàn)了請(qǐng)求者和接受者之間的解耦,并且在客戶端可以實(shí)現(xiàn)動(dòng)態(tài)的組合職責(zé)鏈。使編程更有靈活性。
1.2 定義
使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系田巴。將這些對(duì)象形成一條鏈,并沿著這條鏈傳遞該請(qǐng)求挟秤,直到有對(duì)象處理它為止壹哺。其過(guò)程實(shí)際上是一個(gè)遞歸調(diào)用。
1.3 使用場(chǎng)景
- 有多個(gè)的對(duì)象可以處理一個(gè)請(qǐng)求艘刚,哪個(gè)對(duì)象處理該請(qǐng)求運(yùn)行時(shí)刻自動(dòng)確定管宵。。
- 在請(qǐng)求處理者不明確的情況下向多個(gè)對(duì)象中的一個(gè)提交請(qǐng)求攀甚。
- 需要?jiǎng)討B(tài)指定處理一個(gè)請(qǐng)求的對(duì)象集合箩朴。
2、責(zé)任鏈模式UML類圖
角色:
- Handler:定義職責(zé)接口秋度,通常在內(nèi)部定義處理請(qǐng)求的方法炸庞,可以在這里實(shí)現(xiàn)后繼鏈。
- ConcreteHandler:實(shí)際的職責(zé)類荚斯,在這里個(gè)類里面埠居,實(shí)現(xiàn)在它職責(zé)范圍內(nèi)的請(qǐng)求處理,如果不處理事期,就繼續(xù)轉(zhuǎn)發(fā)請(qǐng)求給后繼者滥壕。
- Client:客戶端,組裝職責(zé)鏈兽泣,向鏈上的具體對(duì)象提交請(qǐng)求捏浊。
圖中最關(guān)鍵的點(diǎn)就是:那條從Handler出發(fā)又指向自己的線,它就是實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用的關(guān)鍵撞叨。
3、責(zé)任鏈模式簡(jiǎn)單實(shí)現(xiàn)
Handler
/**
* 抽象的處理類
* Created by Administrator on 2018/1/25.
*/
public abstract class Handler {
public Handler nextHandler;
/**
*
*/
public void handRequest(AbstractRequest request){
if(request.getRequestLevel()==getHandlerLevel()){
handle(request);
}else {
if(nextHandler!=null){
nextHandler.handRequest(request);
}else {
System.out.println("----> 所有處理對(duì)象 都不能處理 " );
}
}
}
/**
* 具體的處理方法浊洞,給子類實(shí)現(xiàn)
* @param request
*/
public abstract void handle(AbstractRequest request);
/**
* 能夠處理請(qǐng)求的級(jí)別
* @return
*/
public abstract int getHandlerLevel();
}
ConcreteHandler
/**
* 具體處理者
*/
public class Handler1 extends Handler {
@Override
public void handle(AbstractRequest request) {
System.out.println("handle1---->處理了對(duì)象" + request.getRequestLevel());
}
@Override
public int getHandlerLevel() {
return 1;
}
}
public class Handler2 extends Handler {
@Override
public void handle(AbstractRequest request) {
System.out.println("handle2---->處理了對(duì)象" + request.getRequestLevel());
}
@Override
public int getHandlerLevel() {
return 2;
}
}
public class Handler3 extends Handler {
@Override
public void handle(AbstractRequest request) {
System.out.println("handle3---->處理了對(duì)象" + request.getRequestLevel());
}
@Override
public int getHandlerLevel() {
return 3;
}
}
public class Handler4 extends Handler {
@Override
public void handle(AbstractRequest request) {
System.out.println("handle4---->處理了對(duì)象" + request.getRequestLevel());
}
@Override
public int getHandlerLevel() {
return 4;
}
}
處理對(duì)象Request
public abstract class AbstractRequest {
private Object object;
public Object getContent(){
return object;
}
public abstract int getRequestLevel();
}
public class Request1 extends AbstractRequest {
@Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest {
@Override
public int getRequestLevel() {
return 2;
}
}
Client
public class Client {
public static void main(String[] args){
Handler handler1 = new Handler1();
Handler handler2 = new Handler2();
Handler handler3 = new Handler3();
Handler handler4 = new Handler4();
//拼裝成鏈子
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
handler3.nextHandler = handler4;
AbstractRequest request = new Request1();
//一定要將請(qǐng)求對(duì)象牵敷,丟給第一個(gè)處理者
handler1.handRequest(request);
AbstractRequest request2 = new Request2();
//handler1 不處理 交給handler2處理
handler1.handRequest(request2);
}
}
運(yùn)行結(jié)果
handle1---->處理了對(duì)象1
handle2---->處理了對(duì)象2
對(duì)于責(zé)任鏈來(lái)說(shuō),一個(gè)請(qǐng)求最終只有兩種情況:一是被某個(gè)處理對(duì)象處理法希,另一個(gè)是所有的對(duì)象均為對(duì)其處理枷餐。 對(duì)于前一種情況,我們稱該對(duì)象為純的責(zé)任鏈苫亦,對(duì)于后一種情況我們稱為不純的責(zé)任鏈毛肋,在實(shí)際應(yīng)用中怨咪,我們所見(jiàn)的責(zé)任鏈模式大多為不純的責(zé)任鏈模式。
4润匙、責(zé)任鏈模式在Android系統(tǒng)中
4.1 View事件的分發(fā)處理
ViewGroup事件投遞的遞歸調(diào)用就類似于一條責(zé)任鏈诗眨,一旦其尋找到責(zé)任者,那么將由責(zé)任者持有并消費(fèi)掉該次事件孕讳,具體體現(xiàn)在View的onTouchEvent方法中返回值的設(shè)置匠楚,如果返回false,那么意味著當(dāng)前的View不會(huì)是該次的責(zé)任人厂财,將不會(huì)對(duì)其持有芋簿;如果返回true,此時(shí)View會(huì)持有該事件并不再向外傳遞璃饱。
4.2 Broadcast廣播機(jī)制
5与斤、總結(jié)
對(duì)于責(zé)任鏈中的一個(gè)處理者對(duì)象,有兩個(gè)行為荚恶。一是處理請(qǐng)求撩穿,二是將請(qǐng)求傳遞到下一節(jié)點(diǎn),不允許某個(gè)處理者對(duì)象在處理了請(qǐng)求后又將請(qǐng)求傳送給上一個(gè)節(jié)點(diǎn)的情況裆甩。
對(duì)于一條責(zé)任鏈來(lái)說(shuō)冗锁,一個(gè)請(qǐng)求最終只有兩種情況。一是被某個(gè)處理對(duì)象所處理嗤栓,另一個(gè)是所有對(duì)象均未對(duì)其處理冻河,對(duì)于前一種情況我們稱為純的責(zé)任鏈模式,后一種為不純的責(zé)任鏈茉帅。實(shí)際中大多為不純的責(zé)任鏈叨叙。
優(yōu)點(diǎn):
職責(zé)鏈模式的最主要功能就是:動(dòng)態(tài)組合,請(qǐng)求者和接受者解耦堪澎。
請(qǐng)求者和接受者松散耦合:請(qǐng)求者不需要知道接受者擂错,也不需要知道如何處理。每個(gè)職責(zé)對(duì)象只負(fù)責(zé)自己的職責(zé)范圍樱蛤,其他的交給后繼者钮呀。各個(gè)組件間完全解耦。
動(dòng)態(tài)組合職責(zé):職責(zé)鏈模式會(huì)把功能分散到單獨(dú)的職責(zé)對(duì)象中昨凡,然后在使用時(shí)動(dòng)態(tài)的組合形成鏈爽醋,從而可以靈活的分配職責(zé)對(duì)象,也可以靈活的添加改變對(duì)象職責(zé)便脊。
缺點(diǎn):
產(chǎn)生很多細(xì)粒度的對(duì)象:因?yàn)楣δ芴幚矶挤稚⒌搅藛为?dú)的職責(zé)對(duì)象中蚂四,每個(gè)對(duì)象功能單一,要把整個(gè)流程處理完,需要很多的職責(zé)對(duì)象遂赠,會(huì)產(chǎn)生大量的細(xì)粒度職責(zé)對(duì)象久妆。
不一定能處理:每個(gè)職責(zé)對(duì)象都只負(fù)責(zé)自己的部分,這樣就可以出現(xiàn)某個(gè)請(qǐng)求跷睦,即使把整個(gè)鏈走完筷弦,都沒(méi)有職責(zé)對(duì)象處理它。這就需要提供默認(rèn)處理送讲,并且注意構(gòu)造鏈的有效性奸笤。