定義
責任鏈模式(Chain Of Responisibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。
這種處理方式想斗羅大陸的主角遇見的事:泰隆想懟唐三,結果打不過。然後他的老子泰諾,出來找唐三,又被唐三擊敗後。再然後,泰諾的老子泰坦,又出來要解決唐三。。。。
責任鏈,就是,請求解決不了,向上傳遞,直到解決。
UML類圖
角色及職能
- Handler:抽象的處理者,定義了一個處理請求的接口,同時含義另外Handler
- ConcreteHandler1,2是具體的處理者,處理它自己負責的請求,可以訪問它的後繼者(即下一個處理者),如果可以處理當前請求,則處理,否則就將該請求交個後繼者去處理,從而形成一個職責鏈
案例
需求
學校的學習小組關於請假
規定:
- 一個小時以內,給自己請假
- 超過一個小鼠,四個小時以內,找自己小組長請假
- 超過四個小時,找老師請假
代碼
Leader
public abstract class Leader {
private Leader next;
public Leader getNext() {
return next;
}
public void setNext(Leader next) {
this.next = next;
}
// 處理請求方法
public abstract void handleRequest(int LeaveDays);
}
YouSelf
public class YouSelf extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays<=1) {
System.out.println("請假成功,你自己批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
GroupLeader
public class GroupLeader extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays<=4) {
System.out.println("請假成功,組長批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
Teacher
public class Teacher extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays>4) {
System.out.println("請假成功,老師批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
Client
public class Client {
public static void main(String[] args) {
// 組裝責任鏈
Leader youSelf = new YouSelf();
Leader groupLeader = new GroupLeader();
Leader teacher = new Teacher();
youSelf.setNext(groupLeader);
groupLeader.setNext(teacher);
// 提交請求
// 第一次請假
youSelf.handleRequest(1);
// 第二次請假
youSelf.handleRequest(3);
// 第三次請假
youSelf.handleRequest(6);
}
}
運行結果
請假成功,你自己批的假
請假成功,組長批的假
請假成功,老師批的假
優缺點
優點
- 降低耦合度。它將請求的發送者和接收者解耦。
- 簡化了對象。使得對象不需要知道鏈的結構。
- 增強給對象指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
- 增加新的請求處理類很方便。
缺點
- 不能保證請求一定被接收。
- 系統性能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成循環調用。
- 可能不容易觀察運行時的特徵,有礙於除錯。
使用場景
- 有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
- 在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
- 可動態指定一組對象處理請求。