小白設計模式:責任鏈模式

定義

將多個接收對象(處理者)組成鏈式結構,按序對輸入的信號事件進行處理直到事件被處理。android

主要組成

抽象處理者(Handler) : 責任鏈上每一環的處理對象,抽象處理接口。bash

具體處理者(concrete Handler) : 實現Handler相關接口,並持有責任鏈上下一個處理者的引用。對輸入的事件進行判斷,符合條件則截斷事件傳遞並進行處理,不然將事件接着往下傳遞。微信

輸入事件(request) : 輸入到責任鏈請求被處理的事件信號框架

UML類圖

框架代碼:

抽象處理者ide

public abstract class Handler {
        //下一個處理者引用,末尾位置沒有則爲null
    	Handler nextHandler;
    	
    	public Handler(Handler nextHandler) {
    		this.nextHandler = nextHandler;
    	}
    	
    	public abstract void handRequest(Request request);
    }
複製代碼

具體處理者測試

//具體處理者1
    public class JsonHandler extends Handler{

    	public JsonHandler(Handler nextHandler) {
    		super(nextHandler);
    	}
    
    	@Override
    	public void handRequest(Request request) {
    		if (request.isJson()) {
    			
    			//添加事件處理代碼
    			System.out.println( "JsonHandler");
    			
    		} else if (nextHandler != null) {
    			
    			//調用下一個處理者處理事件
    			nextHandler.handRequest(request);
    			
    		}
    	}
    }
    
//具體處理者2
    public class XmlHandler extends Handler{

    	public XmlHandler(Handler nextHandler) {
    		super(nextHandler);
    	}
    
    	@Override
    	public void handRequest(Request request) {
    		if (request.isXml()) {
    			
    			//添加事件處理代碼
    			System.out.println( "XmlHandler");
    			
    		} else if (nextHandler != null) {
    			
    			//調用下一個處理者處理事件
    			nextHandler.handRequest(request);
    			
    		}
    	}
    }
    
//具體處理者3
    public class StringHandler extends Handler{

    	public StringHandler(Handler nextHandler) {
    		super(nextHandler);
    	}
    
    	@Override
    	public void handRequest(Request request) {
    		if (request.isString()) {
    			
    			//添加事件處理代碼
    			System.out.println( "StringHandler");
    			
    		} else if (nextHandler != null) {
    			
    			//調用下一個處理者處理事件
    			nextHandler.handRequest(request);
    			
    		}
    	}
    }
複製代碼

模擬事件對象ui

public class Request {
    
    	boolean isJson = false;
    	boolean isXml = false;
    	boolean isString = false;
    	
    	public Request(boolean isJson, boolean isXml, boolean isString) {
    		
    		this.isJson = isJson;
    		this.isXml = isXml;
    		this.isString = isString;
    		
    	}
    	
    	public boolean isJson() {
    		return isJson;
    	}
    	
    	public boolean isXml() {
    		return isXml;
    	}
    	
    	public boolean isString() {
    		return isString;
    	}
    
    }
複製代碼

簡單測試代碼:this

public class Main {
	public static void main(String[] args){
		Handler handler = new JsonHandler(new XmlHandler(new StringHandler(null)));
		handler.handRequest(new Request(false, false, true));
	}
}

打印:
StringHandler
複製代碼

該簡單測試用例的鏈條組成順序爲:spa

JsonHandler --> XmlHandler --> StringHandlercode

則事件的傳遞與處理方向一樣安裝該順序來: JsonHandler.handRequest --> XmlHandler.handRequest --> StringHandler.handRequest

總結

優勢

將事件的發送者與接受處理者解耦。(這邊能夠這麼理解,假設不使用責任鏈,若是有5種事件對應能夠處理的5個處理者,則調用方須要建立這5個處理者,而且一一調用各自的處理事件的方法。可是若是使用責任鏈,調用者不用關心有多少個處理者,由於提供給調用者的就只是責任鏈上的第一個元素,提供的是接口,至關於將整個責任鏈看作一個對象以接口的形式傳遞給調用者,調用者只須要調用這個對象的處理接口便可。)

簡化了單個處理者處理邏輯,不須要判斷並處理各類事件類型。處理者處不須要知道鏈的總體結構(但須要知道下一個處理者),只須要判斷處理傳遞給本身的事件,若是沒法處理則傳遞給下一個處理者。

能夠動態的改變、調整責任鏈的成員組成,達到增長/刪除或改變處理者的處理順序。

缺點

可能存在事件傳遞到最後都沒有被處理的狀況(既是優勢也是缺點)

效率上的影響,畢竟比全部處理都寫在一塊兒相比多了建立各個對象的消耗等

不容易觀察運行時特徵,排查問題相對麻煩

使用場景

多個對象都須要判斷處理同一種事件類型時,例如android系統中事件分發等,這種鏈條式處理消息的場景。

掃碼微信,關注公衆號

相關文章
相關標籤/搜索