顧名思義,責任鏈模式(Chain of Responsibility Pattern)為請求建立了一個接收者對象的鏈。這種模式給予請求的類型,對請求的寄件者和接收者進行解耦。這種類型的設計模式屬於行為型模式。在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。
主要解決職責鏈上的處理者負責處理請求,客戶只需要將請求發送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的寄件者和請求的處理者解耦了。
大話設計模式中,程傑老師給出的定義是,責任鏈模式:避免請求寄件者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象串連成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。
在責任鏈模式中發出請求的用戶端並不知道這當中的哪個對象最終處理這個請求,這樣系統的更改可以在不影響用戶端的情況下動態重新組織和分配責任。
實現原理:
Handler 裡面彙總它自己,在 HandlerRequest 裡判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。
最重要的兩點,一個是你需要事先給每個具體管理者設定它的上司是哪個類,也就是設定後繼者。另一點就是你需要在每個具體管理者處理請求時,做出判斷,是可以處理這個請求,還是必須要“推卸責任”,轉移給後繼者去處理。
使用情境:
1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
3、可動態指定一組對象處理請求。
責任鏈模式結構圖:
結構圖解析:
Handler定義一個處理請示的介面;
ConcreteHandler具體處理者類,處理它所負責的請求,可訪問它的後繼者,如果可以處理該請求,就處理,否則就將該請求轉寄給它的後繼者。
代碼實現:
package com.response;public abstract class Handler { protected Handler successor;//繼任者 public Handler getSuccessor() { return successor; } public void setSuccessor(Handler successor) { this.successor = successor; } //處理請求 public void handleRequest(int request) {}}
package com.response;/** * 當請求數在0~10之間時有權處理,否則轉到下一位 * @author LMB * */public class ConcreteHandlerA extends Handler { public void handleRequest(int request) { if (request >= 0 && request < 10) { System.out.println(this.getClass() + " 處理請求 " + request); }else if (successor != null) { successor.handleRequest(request); } }}
package com.response;/** * 當請求數在10~20之間時有權處理,否則轉到下一位 * @author LMB * */public class ConcreteHandlerB extends Handler { public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println(this.getClass() + " 處理請求 " + request); }else if (successor != null) { successor.handleRequest(request); } }}
package com.response;/** * 當請求數在20~30之間時有權處理,否則轉到下一位 * @author LMB * */public class ConcreteHandlerC extends Handler { public void handleRequest(int request) { if (request >= 20 && request < 30) { System.out.println(this.getClass() + " 處理請求 " + request); }else if (successor != null) { successor.handleRequest(request); } }}
package com.response;public class ResponseChainPatternDemo { public static void main(String[] args) { Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); Handler handlerC = new ConcreteHandlerC(); //設定責任鏈的前驅和後繼 handlerA.setSuccessor(handlerB); handlerB.setSuccessor(handlerC); int[] requests = {2,5,14,22,18,27,20}; for (int request : requests) { handlerA.handleRequest(request); } }}
運行結果:
優點:
1、降低耦合度。它將請求的寄件者和接收者解耦。
2、簡化了對象。使得對象不需要知道鏈的結構。
3、增強給對象指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
4、增加新的請求處理類很方便。
缺點:
1、不能保證請求一定被接收。
2、系統效能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成迴圈調用。
3、可能不容易觀察運行時的特徵,有礙於除錯。