設計模式——責任鏈模式詳解
0. 前言
寫在最前面,本人的設計模式類博文,建議先看博文前半部分的理論介紹,再看後半部分的例項分析,最後再返回來複習一遍理論介紹,這時候你就會發現我在重點處標紅的用心,對於幫助你理解設計模式有奇效哦~本文原創,轉載請註明出處為的部落格。
責任鏈模式是行為型設計模式之一。鏈中的每個節點即一個物件,每一個物件擁有不同的處理邏輯,請求從鏈的首端發出,依次傳遞給每個節點物件,直到有物件處理這個請求為止。這就是所謂的責任鏈模式。
1. 責任鏈模式介紹
責任鏈模式定義:
使多個物件都有機會處理請求,從而避免了請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞請求,直到某個物件處理了這個請求。
責任鏈模式的使用場景:
多個物件可處理同一個請求,但是到底誰處理要動態決定。但是還是要向多個物件中的一個提交請求。
享元模式包括的角色:
(1)抽象處理者Handler類:宣告一個處理請求的方法,並在其中保持對下一個處理Handler節點的引用。
(2)具體處理者ConcreteHandler類:具體的處理類,如果不負責該類的處理條件則將請求交給下一個處理者。
2. 責任鏈模式通用模版程式碼
從下面程式碼中可以看出,ConcreteHandlerA中持有了ConcreteHandlerB的引用,ConcreteHandlerB中持有了ConcreteHandlerA的引用,兩者均可根據請求引數決定自己處理請求,或者是給下一個處理者處理請求。
/** * Iterator Pattern * Created by Calvin on 2017/5/4. */ public class Iterator { public static void main(String[] args) { ConcreteHandlerA a = new ConcreteHandlerA(); ConcreteHandlerB b = new ConcreteHandlerB(); a.myHandler = b; b.myHandler = a; a.function("B"); } public static class ConcreteHandlerA extends Handler{ @Override public void function(String condition) { if(condition.equals("A")){ System.out.println("ConcreteHandlerA handle this"); }else{ myHandler.function(condition); } } } public static class ConcreteHandlerB extends Handler{ @Override public void function(String condition) { if(condition.equals("B")){ System.out.println("ConcreteHandlerB handle this"); }else{ myHandler.function(condition); } } } public static abstract class Handler { protected Handler myHandler; public abstract void function(String condition); } }
3. 責任鏈模式例項程式碼
這裡引入一個例項,在公司裡作為新人肯定會遇到很多難題,不會的問題可以向師兄、技術主管、技術總監虛心請教,師兄、技術主管、技術總監能解決的問題難度不一樣,比如師兄可以解決難度<=10的問題、主管可以解決難度<=20的問題、總監可以解決難度<=30的問題。這個場景就可以使用責任鏈模式進行解決。
/**
* Iterator Pattern
* Created by Calvin on 2017/5/4.
*/
public class Iterator {
public static void main(String[] args) {
ShiXiong shiXiong = new ShiXiong();
ZhuGuan zhuGuan = new ZhuGuan();
ZongJian zongJian = new ZongJian();
shiXiong.nextRespondent = zhuGuan;
zhuGuan.nextRespondent = zongJian;
zongJian.nextRespondent = null;
shiXiong.handleQuestion(21);
}
public static abstract class Respondent {
protected Respondent nextRespondent;
public final void handleQuestion(int level){
if(level <= getRespondentLevel()){
//該類自己處理
handle(level);
}else {
if(nextRespondent !=null ){
//下一個處理物件處理
nextRespondent.handleQuestion(level);
}else {
//沒有人可以處理該請求
System.out.println("Nobody can handle this request.");
}
}
}
public abstract int getRespondentLevel();
public abstract void handle(int level);
}
public static class ShiXiong extends Respondent{
@Override
public int getRespondentLevel() {
return 10;
}
@Override
public void handle(int level) {
System.out.println("師兄解決了難度為" + level + "的問題");
}
}
public static class ZhuGuan extends Respondent{
@Override
public int getRespondentLevel() {
return 20;
}
@Override
public void handle(int level) {
System.out.println("主管解決了難度為" + level + "的問題");
}
}
public static class ZongJian extends Respondent{
@Override
public int getRespondentLevel() {
return 30;
}
@Override
public void handle(int level) {
System.out.println("總監解決了難度為" + level + "的問題");
}
}
}
4. 責任鏈模式總結
責任鏈模式的靈活之處在於,可以靈活改變責任鏈的結構,比如上個例子中可以直接越過主管直接向總監請教。還有就是請求者和處理者之間的解耦。缺點在於處理者過多的情況,遍歷處理者勢必會影響效能。
在Android中,ViewGroup的事件傳遞機制的遞迴呼叫就類似於責任鏈模式。一旦找到處理者,則該處理者就會消耗掉該點選事件,否則會將該事件向外傳遞。