定義:
責(zé)任鏈模式:為了避免請(qǐng)求發(fā)送者與多個(gè)請(qǐng)求處理者耦合在一起捶牢,此模式會(huì)創(chuàng)建一個(gè)請(qǐng)求處理的”鏈“,當(dāng)”鏈“ 中的 當(dāng)前節(jié)點(diǎn)不能處理此請(qǐng)求時(shí)烁挟,會(huì)傳遞給”鏈“中的下一個(gè)對(duì)象處理,以此類(lèi)推直到能處理/到達(dá)”鏈“結(jié)尾為止。
主要組成結(jié)構(gòu)
- 抽象處理類(lèi)
- 具體處理類(lèi)
- 調(diào)用者
優(yōu)缺點(diǎn)
-
優(yōu)點(diǎn)
解耦:調(diào)用者將請(qǐng)求發(fā)給”責(zé)任鏈“即可蒙揣,無(wú)需知道具體處理類(lèi)的 具體信息;
可擴(kuò)展:增加新的 處理責(zé)任的需求卖擅,只需要新增具體的處理類(lèi)鸣奔,調(diào)用者使用的時(shí)候 加到“責(zé)任鏈”中即可墨技,無(wú)需修改原業(yè)務(wù)代碼;符合開(kāi)閉原則
靈活:調(diào)用者可以根據(jù)自己的需求和 處理順序挎狸,創(chuàng)建“責(zé)任鏈”;當(dāng)需求有變化時(shí)扣汪,根據(jù)需求重新構(gòu)建”責(zé)任鏈“即可;類(lèi)似活字印刷術(shù)
依賴(lài)簡(jiǎn)化:每個(gè)處理類(lèi)只需要通過(guò)next指針以來(lái)一個(gè)具體處理類(lèi)即可锨匆;無(wú)需依賴(lài)鏈中的所有處理類(lèi)對(duì)象
職責(zé)單一:每個(gè)具體處理類(lèi)崭别,只負(fù)責(zé)自己的任務(wù),自己不能處理的任務(wù)往后傳遞即可恐锣;符合單一職責(zé)原則茅主;
-
缺點(diǎn)
- 不能保證處理一定能被處理,有可能 “責(zé)任鏈”中的所有處理類(lèi)土榴,均不能處理此次請(qǐng)求
- 責(zé)任鏈太長(zhǎng)會(huì)影響系統(tǒng)性能
- 責(zé)任鏈由 調(diào)用方維護(hù)诀姚;增加了調(diào)用方的系統(tǒng)復(fù)雜度,并且調(diào)用方要 清楚有哪些處理類(lèi)及其作用
應(yīng)用場(chǎng)景
- 過(guò)濾器
- 審批業(yè)務(wù)
- 攔截器
- ... ...
實(shí)際案例
案例分析
具體業(yè)務(wù)邏輯
請(qǐng)假審批流程:
請(qǐng)假 <3天 組長(zhǎng)審批
3~5 部門(mén)經(jīng)理審批
5~ 副總審批
代碼實(shí)現(xiàn)
/**
* description 責(zé)任鏈模式
* 請(qǐng)假 <3天 組長(zhǎng) 3~5 部門(mén)經(jīng)理 5~ 副總
*
* @author yufengwen
* @date 2021/12/21 11:25 上午
*/
public class ChainOfResponsibility {
public static void main(String[] args) {
final Approver groupLeader = new GroupLeader();
final Approver deptLeader = new DeptLeader();
final Approver vicePresident = new VicePresident();
groupLeader.setNextApprover(deptLeader);
deptLeader.setNextApprover(vicePresident);
groupLeader.approve(2);
groupLeader.approve(4);
groupLeader.approve(8);
}
}
/**
* 審批人
*/
abstract class Approver {
public Approver nextApprover;
/**
* 審批
*
* @return
*/
abstract Boolean approve(Integer days);
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
}
/**
* 組長(zhǎng)
*/
class GroupLeader extends Approver {
/**
* 審批
*
* @param days
* @return
*/
@Override
public Boolean approve(Integer days) {
System.out.print("請(qǐng)假天數(shù):" + days + " ;");
if (days == null || days < 3) {
System.out.println("組長(zhǎng)審批完成");
return true;
}
if (nextApprover != null) {
return nextApprover.approve(days);
}
return false;
}
}
/**
* 部門(mén)leader
*/
class DeptLeader extends Approver {
/**
* 審批
*
* @param days
* @return
*/
@Override
public Boolean approve(Integer days) {
if (days >= 3 && days < 5) {
System.out.println("部門(mén)經(jīng)理審批完成");
return true;
}
if (nextApprover != null) {
return nextApprover.approve(days);
}
return false;
}
}
/**
* 副總
*/
class VicePresident extends Approver {
/**
* 審批
*
* @param days
* @return
*/
@Override
public Boolean approve(Integer days) {
if (days >= 5) {
System.out.println("副總審批完成");
return true;
}
if (nextApprover != null) {
return nextApprover.approve(days);
}
return false;
}
}
結(jié)果
請(qǐng)假天數(shù):2 ;組長(zhǎng)審批完成
請(qǐng)假天數(shù):4 ;部門(mén)經(jīng)理審批完成
請(qǐng)假天數(shù):8 ;副總審批完成