責任鏈模式(Chain of Responsibility Pattern)
定義:
責任鏈模式(Chain of Responsibility Pattern)爲請求創建了一個接收者對象的鏈。
責任鏈模式是一種對象的行爲模式。
在責任鏈模式裏,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。
這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。鏈有起始對象,有終止對象。
意圖:避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿着這條鏈傳遞請求,直到有對象處理它爲止。
何時使用:在處理消息的時候以過濾很多道。
如何解決:攔截的類都實現統一接口。
應用實例:retrofit的攔截器。
使用場景: 1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。 2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。 3、可動態指定一組對象處理請求。
demo:模擬一個請假的流程,員工請假需要上級批准,對不同的請假天數,各個領導的權限不一樣。
LeaveRequest.java
public class LeaveRequest {
private String name;
private int leaveDays;
private String reason;
public LeaveRequest(String name, int leaveDays, String reason) {
super();
this.name = name;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
創建抽象的記錄器類。
public abstract class Leader {
String name;
Leader nextLeader; //責任鏈上的後繼對象
public Leader(String name) {
super();
this.name = name;
}
// 設定責任鏈上的後繼對象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
public abstract void handleRequest(LeaveRequest request);
}
創建擴展了該記錄器類的實體類。
Director.java
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //獲取請假天數
String name = request.getName(); //獲取請假人姓名
String reason = request.getReason(); // 獲取請假理由
if(days <= 3) { //如果滿足3天內的要求,主任直接審批
System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
System.out.println("主任" + this.name + "審批通過");
} else {
System.out.println("請假天數過多,主任" + this.name + "沒法處理");
if(this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
this.nextLeader.handleRequest(request);
}
}
}
}
Manager.java
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //獲取請假天數
String name = request.getName(); //獲取請假人姓名
String reason = request.getReason(); // 獲取請假理由
if (days <= 10) { //如果滿足10天內的要求,經理直接審批
System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
System.out.println("經理" + this.name + "審批通過");
} else {
System.out.println("請假天數過多,經理" + this.name + "沒法處理");
if (this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
this.nextLeader.handleRequest(request);
}
}
}
}
GeneralManager.java
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //獲取請假天數
String name = request.getName(); //獲取請假人姓名
String reason = request.getReason(); // 獲取請假理由
if (days <= 30) { //如果滿足30天內的要求,總經理直接審批
System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
System.out.println("總經理" + this.name + "審批通過");
} else {
System.out.println("請假天數過多,總經理" + this.name + "沒法處理");
if (this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
this.nextLeader.handleRequest(request);
} else {
System.out.println("請假不成功");
}
}
}
}
TestDemo.java
public static void main(String[] args) throws Exception {
Leader director = new Director("張三");
Leader manager = new Manager("李四");
Leader gManager = new GeneralManager("王五");
director.setNextLeader(manager);
manager.setNextLeader(gManager);
// 開始請假操作
LeaveRequest request = new LeaveRequest("倪升武", 15, "在家睡覺");
director.handleRequest(request);
}
運行結果
請假天數過多,主任張三沒法處理
請假天數過多,經理李四沒法處理
員工倪升武請假15天,理由:在家睡覺
總經理王五審批通過