1. 程式人生 > >設計模式——責任鏈模式詳解

設計模式——責任鏈模式詳解

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的事件傳遞機制的遞迴呼叫就類似於責任鏈模式。一旦找到處理者,則該處理者就會消耗掉該點選事件,否則會將該事件向外傳遞。