一、定義
使多個對象都有機會處理請求,從而避免了請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞請求,直到有對象處理它為止。
二、適用場景
- 多個對象可以處理同一請求,但具體由哪個對象處理則在運行時動態(tài)決定。
- 在請求處理著不明確的情況下向多個對象中的一個提交一個請求。
- 需要動態(tài)指定一組對象處理請求。
責任鏈模式在View事件分發(fā)中、OkHttp中都有見到。應(yīng)用面還是很多的。
三、實現(xiàn)
以一個員工報銷的場景來說,每一級的領(lǐng)導能報銷的項目額度是有最大限制的。
1. UML

2. 抽象領(lǐng)導(處理者)
封裝了轉(zhuǎn)發(fā)消耗的判斷邏輯,剩下判斷限制和具體處理交給具體的處理者去實現(xiàn)。
public abstract class Leader {
protected Leader nextHandler;
// 統(tǒng)一實現(xiàn)的轉(zhuǎn)發(fā)消耗邏輯
public final void handleRequest(int money) {
if (money <= limit()) {
// 消耗
handle(money);
} else {
// 上層領(lǐng)導不空就轉(zhuǎn)交
if (nextHandler != null) {
nextHandler.handleRequest(money);
}
}
}
// 具體的領(lǐng)導實現(xiàn)具體的額度限制
public abstract int limit();
// 具體領(lǐng)導實現(xiàn)具體報銷方式
public abstract void handle(int money);
}
3. 具體領(lǐng)導
需要實現(xiàn)自己的額度限制方法和具體處理的方法。
public class Director extends Leader {
@Override
public int limit() {
return 1000;
}
@Override
public void handle(int money) {
System.out.println("director handle " + money);
}
}
public class Manager extends Leader {
@Override
public int limit() {
return 10000;
}
@Override
public void handle(int money) {
System.out.println("manager handle " + money);
}
}
public class Boss extends Leader {
@Override
public int limit() {
return Integer.MAX_VALUE;
}
@Override
public void handle(int money) {
System.out.println("boss handle " + money);
}
}
4. 使用
自己構(gòu)造責任鏈,之后調(diào)用Director的處理方法。
public class Test {
public static void main(String[] args) {
Director director = new Director();
Manager manager = new Manager();
Boss boss = new Boss();
// 連接責任鏈
director.nextHandler = manager;
manager.nextHandler = boss;
// 調(diào)用最低級領(lǐng)導的方法
director.handleRequest(2222);
}
}
可以看到,Test訪問了Director一個處理者,完全不需要知道其他處理者的存在,這就達到了請求和處理的解耦。
四、小結(jié)
優(yōu)點:
請求者和處理者關(guān)系解耦,提高代碼的靈活性。
缺點:
如果處理者過多,遍歷會影響性能,特別如果有遞歸調(diào)用時需要慎重。