責任鍊模式(Chain of Responsibility)是一種對象的行為模式。
在責任鍊模式裡,很多對象由每一個對象對其下家的引用而連接配接起來形成一條鍊。
請求在這個鍊上傳遞,直到鍊上的某一個對象決定處理此請求。
發出這個請求的用戶端并不知道鍊上的哪一個對象最終處理這個請求,這使得系統可以在不影響用戶端的情況下動态的重新組織鍊和配置設定責任。
責任鍊可能是一條直線、一個環鍊或者一個樹結構的一部分。
責任鍊的結構
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2Pn5GcuYGOuVDMwZDMzY3LcJDN5YDM3czLcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
角色如下:
抽象處理者角色(Handler): 定義出一個處理請求的接口。如果需要,接口可以定義出一個方法,以設定和傳回對下家的引用。這個角色通常由一個java抽象類或java接口實作。
具體處理者角色(ConcreteHandler): 具體處理者接到請求後,可以選擇将請求處理掉,或者将請求傳給下家。由于具體處理者持有對下家的引用,是以,如果需要,具體處理者可以通路下家。
源碼清單:
抽象處理者
public abstract class Handler {
protected Handler successor;
/**
* 處理方法:調用此方法處理請求
*/
public abstract void handleRequest();
/**
* 指派方法:調用此方法設定下家
* @param successor
*/
public void setSuccessor(Handler successor){
this.successor = successor;
}
/**
* 取值方法
* @return
*/
public Handler getSuccessor(){
return successor;
}
}
複制
具體處理者
public class ConcreteHandler extends Handler {
/**
* 處理方法,調用此方法處理請求
*/
@Override
public void handleRequest() {
if(getSuccessor()!=null){
System.out.println("The request is passed to "+getSuccessor());
getSuccessor().handleRequest();
}else{
System.out.println("The request is handled here.");
}
}
}
複制
用戶端
public class Client {
static private Handler handler1,handler2;
public static void main(String[] args) {
handler1 = new ConcreteHandler();
handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
handler1.handleRequest();
}
}
複制
可以看出,用戶端建立了兩個處理者對象,并指定第一個處理者對象的下家是第二個處理者對象,而第二個處理者對象沒有下家。然後用戶端将請求傳遞給第一個處理者對象。
這裡的這個邏輯很簡單:隻要有下家,就傳遞給下家;如果沒有下家,就自行處理。
活動時序圖
純的與不純的責任鍊模式
一個純的責任鍊模式要求一個具體的處理者對象隻能在兩個行為中選擇一個;
一是承擔責任,二是把責任推給下家。不允許出現某一個具體處理者對象在承擔了一部分責任後又把責任向下傳遞。
在一個純的責任鍊模式裡面,一個請求必須被某一個處理者對象所接收;
在一個不純的責任鍊模式裡面,一個請求可以最終不被任何接收端對象所接收。
純的責任鍊模式的實際例子很難找到,一般看到的例子均是不純的責任鍊模式的實作。
什麼情況下會使用責任鍊模式
1. 系統已經有一個由處理者對象組成的鍊。這個鍊可能由合成模式給出。
2. 有多于一個的處理者對象會處理一個請求,而且事先并不知道到底由哪一個處理者對象處理一個請求。這個處理者對象時動态确定的。
3. 系統想發出一個請求給多個處理者對象中的某一個,但是不明顯指出是哪一個處理者對象會處理此請求。
4. 處理一個請求的處理者對象集合需要動态的指定時。
責任鍊模式降低了發出指令的對象和處理指令的對象之間的耦合,它允許多于一個的處理者對象根據自己的邏輯來決定哪一個處理者最終處理這個指令。
責任鍊模式的實作
鍊結構的由來
值得指出的是,責任鍊模式并不建立出責任鍊。責任鍊的建立必須由系統的其他部分建立出來。
一個鍊可以是一條線,一個樹,也可以是一個環。鍊的拓撲結構可以是單連通的或多連通的,責任鍊模式并不指定責任鍊的拓撲結構。
如下圖,責任鍊式一個樹結構的一部分
指令的傳遞
在一個責任鍊上傳遞的可能不隻有一個指令,而是數個指令。