簡介
責任鏈模式的定義:使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係
將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理他為止。
圖例
責任鏈-根據事情大小來決定責任向上冒泡到誰身上
場景設定
如上圖-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類圖
總結
優點:
- 將請求的傳送者和接受者解耦
- 可以簡化你的物件,因為它不需要知道鏈的結構
- 通過改變鏈內的成員和次序,允許你動態的新增和刪除責任
缺點:
- 物件變得多了,相應物件管理比較複雜
- 一個請求有可能末端都得不到處理,或者因為沒有正確配置沒有處理
更多精彩內容,歡迎關注熱心的小宇公眾號 (呆呆熊一點通):