設計模式第七講-責任鏈模式
責任鏈模式的定義:使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係
將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理他為止。
圖例
責任鏈-根據事情大小來決定責任向上冒泡到誰身上

場景設定
如上圖-DBA某人把線上資料庫刪了
不好的程式碼實現
package responsibility; /** * 事故類 */ public class Accident { //緊急程度 private int fireLevel = 0; public Accident(int fireLevel) { this.fireLevel = fireLevel; } /** * 事件處理 */ public void fire() { if (this.fireLevel < 2) { System.out.println("運維組長處理了"); } else if (this.fireLevel < 5) { System.out.println("CTO處理了"); } else { System.out.println("BOSS處理了"); } } } 複製程式碼
呼叫(傳入事件等級):
Accident accident = new Accident(3); accident.fire(); 複製程式碼
output:
CTO處理了 複製程式碼
使用責任鏈模式
首先設定下請求物件(方便呼叫傳參):
package responsibility; public class Request { private String requestMsg; private Integer requestLevel; public Request(String requestMsg, int requestLevel) { this.requestMsg = requestMsg; this.requestLevel = requestLevel; } public String getRequestMsg() { return this.requestMsg; } public Integer getRequestLevel() { return this.requestLevel; } } 複製程式碼
設定基類handler
package responsibility; public abstract class Handler { /** * 管理者名字 */ protected String name; /** * 管理者物件 */ protected Handler superior; public Handler(String name) { this.name = name; } //設定管理者上級 public void SetHandler(Handler superior) { this.superior = superior; } //緊急請求 abstract public void Fire(Request request); } 複製程式碼
運維組長職能類
package responsibility; public class OperationLeader extends Handler { public OperationLeader(String name) { super(name); } /** * 運維組長處理 * * @param request */ public void Fire(Request request) { if (request.getRequestLevel() < 2) { System.out.println(this.name + "處理了" + request.getRequestMsg()); } else { if (this.superior != null) { this.superior.Fire(request); } } } } 複製程式碼
CTO類
package responsibility; public class CtoLeader extends Handler { public CtoLeader(String name) { super(name); } /** * CTO處理 * * @param request */ public void Fire(Request request) { if (request.getRequestLevel() < 5) { System.out.println(this.name + "處理了" + request.getRequestMsg()); } else { if (this.superior != null) { this.superior.Fire(request); } } } } 複製程式碼
大boss類
package responsibility; public class Boss extends Handler { public Boss(String name) { super(name); } /** * CTO處理 * * @param request */ public void Fire(Request request) { System.out.println(this.name + "處理了" + request.getRequestMsg()); } } 複製程式碼
呼叫:
Request request = new Request("xx資料庫被刪了", 3); OperationLeader operationLeader = new OperationLeader("運維組長"); CtoLeader ctoLeader = new CtoLeader("CTO"); Boss boss = new Boss("野獸"); //DBA上級 operationLeader.SetHandler(ctoLeader); //運維組長上級 ctoLeader.SetHandler(boss); //boss兜底 //最先收到事故的為運維組長 operationLeader.Fire(request); 複製程式碼
output:
Request request = new Request("xx資料庫被刪了", 3); OperationLeader operationLeader = new OperationLeader("運維組長"); CtoLeader ctoLeader = new CtoLeader("CTO"); Boss boss = new Boss("野獸"); //DBA上級 operationLeader.SetHandler(ctoLeader); //運維組長上級 ctoLeader.SetHandler(boss); //boss兜底 //DBA最先報警 operationLeader.Fire(request); 複製程式碼
UML類圖

總結
優點:
- 將請求的傳送者和接受者解耦
- 可以簡化你的物件,因為它不需要知道鏈的結構
- 通過改變鏈內的成員和次序,允許你動態的新增和刪除責任
缺點:
- 物件變得多了,相應物件管理比較複雜
- 一個請求有可能末端都得不到處理,或者因為沒有正確配置沒有處理
更多精彩內容,歡迎關注熱心的小宇公眾號 (呆呆熊一點通):
