設計模式11:責任鏈模式
阿新 • • 發佈:2018-11-07
責任鏈模式
定義:為了避免請求傳送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈,並且沿著這條鏈傳遞請求,直到有物件處理它為止,這就是責任鏈模式。
舉個栗子咯,當週杰倫要在你的城市開演唱會時,而你恰好有課,這時候咋辦呢?總不能不去吧,所以只有向老師請假咯。而請假的話,是有個流程滴,當你提交申請表給輔導員時,如果天數在兩天以內的話,輔導員直接給你批准啦,你就可以開溜啦;但是當你請假天數在兩天以上,四天以內的時候,輔導員就沒那個權力批准啦,它就只能把你的申請表交給學院院長,讓院長批准啦;如果天數在四天到七天的話,院長也沒法子處理啦,他只有把你的請假申請表交給校長啦;如果請假天數大於七天...抱歉,請假七天那還讀個毛的書,一律否決,再附送個叫家長來校大禮包....
用程式語言來實現的話,估計很多人第一想到的就是寫一大串if else 語句啦,但在之前討論策略模式的時候,我們就以及說過了這樣的弊端啦,所以我們就要用到我們的責任鏈模式啦
主要角色
Handler: 抽象處理者。定義了一個處理請求的方法。所有的處理者都必須實現該抽象類。
ConcreteHandler: 具體處理者。處理它所負責的請求,同時也可以訪問它的後繼者。如果它能夠處理該請求則處理,否則將請求傳遞到它的後繼者。
Client: 事件的發起者
例項
首先定義一個假條類
public class LeaveRequest { private String name; private int leaveDays; public LeaveRequest(String name, int leaveDays) { super(); this.name = name; this.leaveDays = leaveDays; } 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 abstract class Leader { protected String name; protected Leader nextLeader; //責任鏈上的後繼物件 public Leader(String name) { super(); this.name = name; } //設定責任鏈上的後繼物件 public void setNextLeader(Leader nextLeader) { this.nextLeader = nextLeader; } /** * 處理請求的核心的業務方法 * @param request */ public abstract void handleRequest(LeaveRequest request); }
三個具體的處理者
輔導員
public class Instructor extends Leader{
public Instructor(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 2){ //小於2天輔導員審批
System.out.println("輔導員" + name + "審批" +LeaveRequest.getName() + "同學的請假條,請假天數為" + LeaveRequest.getLeaveDays()+ "天。");
}
else{ //否則傳遞給院長
if(this.nextLeader != null){
this.nextLeader.handleRequest(LeaveRequest);
}
}
}
}
院長
public class Dean extends Leader{
public Dean(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 4){ //小於4天院長審批
System.out.println("院長" + name + "審批" +LeaveRequest.getName() + "同學的請假條,請假天數為" + LeaveRequest.getLeaveDays()+ "天。");
}
else{ //否則傳遞給校長
if(this.nextLeader != null){
this.nextLeader.handleRequest(LeaveRequest);
}
}
}
}
校長
public class President extends Leader{
public President(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 7){ //小於7天校長審批
System.out.println("校長" + name + "審批" +LeaveRequest.getName() + "同學的請假條,請假天數為" + LeaveRequest.getLeaveDays()+ "天。");
}
else{
System.out.println("叫家長來");
}
}
}
客戶端測試
public class Client {
public static void main(String[] args) {
Leader instructor = new Instructor("老王"); //輔導員
Leader dean = new Dean("老李"); //院長
Leader president = new President("老謝"); //校長
instructor.setNextLeader(dean); //輔導員的後續者是院長
dean.setNextLeader(president); //院長的後繼者是校長
LeaveRequest le = new LeaveRequest("我", 1);
instructor.handleRequest(le);
le = new LeaveRequest("哥", 3);
instructor.handleRequest(le);
le = new LeaveRequest("qiu", 5);
instructor.handleRequest(le);
le = new LeaveRequest("ll", 11);
instructor.handleRequest(le);
}
}
適用場景
- 有多個物件可以處理同一個請求,具體哪個物件處理該請求由執行時刻自動確定。
- 在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。
- 可動態指定一組物件處理請求。
實際開發中的應用
- Java中,異常機制就是一種責任鏈模式。一個try可以對應多個catch,當第一個catch不匹配型別,則自動跳到第二個catch.
- Javascript語言中,事件的冒泡和捕獲機制。Java語言中,事件的處理採用觀察者模式。
- Servlet開發中,過濾器的鏈式處理