基本介紹
責任鏈模式(chain of Responsibilities Pattern)允許你將請求沿著處理者鏈進行傳送,處理者收到請求後,可以對請求進行處理,或者將其傳遞給下一個處理者。
模式結構
Handler(抽象處理者):定義一個處理請求的介面,並且聚合了一個型別為自身的物件(後繼者),子類可以通過設定後繼者,將請求傳遞下去
ConcreteHandler(具體處理者):具體處理者收到請求後,可以自己將請求處理,或者傳給後繼者。
Request(請求):定義一些屬性,表示一個請求
舉例說明
公司採購審批流程:
- 金額 <= 5000 由組長審批
- 5000 < 金額 <= 10000 由經理審批
- 金額 > 10000 由老闆審批
請求,包含 id 和 價格欄位
public class PurchaseRequest {
private int id;
private float price;
public PurchaseRequest(int id, float price) {
this.id = id;
this.price = price;
}
public int getId() {
return id;
}
public float getPrice() {
return price;
}
}
抽象處理者
public abstract class Approver {
protected String name;
protected Approver approver;
public Approver(String name) {
this.name = name;
}
public void setApprover(Approver approver) {
this.approver = approver;
}
/**
* 處理請求
* @param request
*/
public abstract void processRequest(PurchaseRequest request);
}
具體處理者
public class TeamLeader extends Approver {
public TeamLeader(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getPrice() <= 5000) {
System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
} else {
approver.processRequest(request);
}
}
}
public class Manager extends Approver {
public Manager(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getPrice() > 5000 && request.getPrice() <= 10000) {
System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
} else {
approver.processRequest(request);
}
}
}
public class Boss extends Approver {
public Boss(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getPrice() > 10000) {
System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
} else {
approver.processRequest(request);
}
}
}
測試類
public class Client {
@Test
public void test(){
PurchaseRequest request = new PurchaseRequest(1, 5000);
TeamLeader teamLeader = new TeamLeader("李組長");
Manager manager = new Manager("張經理");
Boss boss = new Boss("王老闆");
teamLeader.setApprover(manager);
manager.setApprover(boss);
boss.setApprover(teamLeader);
manager.processRequest(request);
boss.processRequest(request);
}
}
執行結果
李組長審批了1號請求,價格為5000.0
李組長審批了1號請求,價格為5000.0
模式分析
優點
- 降低耦合度。它將請求的傳送者和接收者解耦
- 簡化了物件。使得物件不需要知道鏈的結構
- 增強給物件指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任
- 增加新的請求處理類很方便
缺點
- 不能保證請求一定被接收
- 系統效能將受到一定影響,而且在進行程式碼除錯時不太方便,可能會造成迴圈呼叫
- 可能不容易觀察執行時的特徵,有礙於除錯
適用場景
- 有多個物件可以處理同一個請求,具體哪個物件處理該請求由執行時刻自動確定
- 在不明確指定接收者的情況下,向多個物件中的一個提交一個請求
- 可動態指定一組物件處理請求