定義
責(zé)任鏈模式屬于行為模式,為請(qǐng)求創(chuàng)建了一個(gè)接收者對(duì)象的鏈,這種模式給于請(qǐng)求的類型,對(duì)請(qǐng)求的發(fā)送者和接收者進(jìn)行解耦。在這種模式中,通常每個(gè)接收者都包含對(duì)另一個(gè)接收者的引用。如果一個(gè)對(duì)象不能處理該請(qǐng)求,那么它會(huì)把相同的請(qǐng)求傳給下一個(gè)接收者,依次類推?;蛘呷绻硞€(gè)接收者處理完之后,還需要傳遞到下一個(gè)接收者繼續(xù)處理或者返回處理完畢
主要解決
職責(zé)鏈上的處理者與接收者耦合在一起,讓多個(gè)對(duì)象都有可能接收到請(qǐng)求,將這些對(duì)象連接成一條鏈,并且沿著這條鏈傳遞請(qǐng)求,直到有對(duì)象處理它為止。
優(yōu)點(diǎn)
- 降低耦合度。它將請(qǐng)求的發(fā)送者和接收者解耦。
- 簡(jiǎn)化了對(duì)象。使得對(duì)象不知道鏈的結(jié)構(gòu)。
- 增加給對(duì)象指派的靈活性。通過(guò)改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,允許動(dòng)態(tài)地新增或者刪除責(zé)任。
- 增加新的請(qǐng)求處理類很方便。
缺點(diǎn)
- 不能保證請(qǐng)求一定被接收。
- 系統(tǒng)性能將受到一定影響,而且在進(jìn)行代碼調(diào)式是不太方便,可能會(huì)造成循環(huán)調(diào)用。
- 可能不容易觀察運(yùn)行時(shí)的特征,有礙于除錯(cuò)。
使用場(chǎng)景
- 有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體哪個(gè)對(duì)象處理該請(qǐng)求由運(yùn)行時(shí)間時(shí)刻自動(dòng)確定。
- 在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。
- 可以動(dòng)態(tài)指定一組對(duì)象處理請(qǐng)求。
示例
場(chǎng)景
小明所在的公司,請(qǐng)假需要領(lǐng)導(dǎo)進(jìn)行審批,如果請(qǐng)假天數(shù)半天到1天,需要主管審批,如果請(qǐng)假1到3天,主管審批完之后,還需要部門(mén)經(jīng)理審批。請(qǐng)假3到30天的,主管和部門(mén)經(jīng)歷審批完之后,還需要總經(jīng)理進(jìn)行處理。
角色
- 員工請(qǐng)求的類:LeaveRequest
- 抽象的責(zé)任處理類:AbstractHandler
- 主管審批的處理類:DirectLeaderHandler
- 部門(mén)經(jīng)理處理類:DeptManagerHandler
- 總經(jīng)理處理類:GManagerHandler
UML類圖

image.png
實(shí)現(xiàn)步驟
- 定義一個(gè)抽象的責(zé)任處理類AbstractHandler,定義一個(gè)抽象方法 handlerRequest的作用是用來(lái)處理請(qǐng)求的。定義一個(gè)設(shè)置下級(jí)的處理者。
public abstract class AbstractHandler {
/**
* 需主管審批的天數(shù)
*/
protected final static int MIN=1;
/**
* 需部門(mén)經(jīng)理審批的天數(shù)
*/
protected final static int MIDDLE=3;
/**
* 需總經(jīng)理歷審批的天數(shù)
*/
protected final static int MAX=30;
protected AbstractHandler nextHandler;
/**
* 設(shè)置下一個(gè)審批者
* @param nextHandler
*/
protected void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 需要子類進(jìn)行重寫(xiě)
* @param request
*/
public abstract void handlerRequest(LeaveRequest request);
}
- 定義主管審批的處理類:DirectLeaderHandler
public class DirectLeaderHandler extends AbstractHandler {
@Override
public void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()<=MIN){
System.out.println("部門(mén)主管:已審批 請(qǐng)假申請(qǐng)通過(guò)");
return;
}
//請(qǐng)假天數(shù)大于1天,需要繼續(xù)傳遞到部門(mén)經(jīng)理進(jìn)行審批
if (request.getLeaveDays()> MIN){
if(nextHandler!=null){
System.out.println("部門(mén)主管:已審批 還需要部門(mén)經(jīng)理審批");
nextHandler.handlerRequest(request);
}
}
}
}
- 定義部門(mén)經(jīng)理:DeptManagerHandler
public class DeptManagerHandler extends AbstractHandler{
@Override
public void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()<=MIDDLE){
System.out.println("部門(mén)經(jīng)理:已審批 請(qǐng)假申請(qǐng)通過(guò)");
return;
}
//請(qǐng)假天數(shù)大于3天,需要繼續(xù)傳遞到總經(jīng)理進(jìn)行審批
if (request.getLeaveDays()> MIDDLE){
if(nextHandler!=null){
System.out.println("部門(mén)經(jīng)理:已審批 還需要總經(jīng)理審批");
nextHandler.handlerRequest(request);
}
}
}
}
- 定義總經(jīng)理處理類:GManagerHandler
public class GManagerHandler extends AbstractHandler{
@Override
public void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()<=MAX){
System.out.println("總經(jīng)理:已審批 請(qǐng)假申請(qǐng)通過(guò)");
return;
}
//如果大于30天的,根據(jù)具體的需要進(jìn)行處理
if (request.getLeaveDays()> MAX){
}
}
}
- 定義員工請(qǐng)求的類:LeaveRequest
/**
* 請(qǐng)假的請(qǐng)求類
*/
public class LeaveRequest {
/**
* 請(qǐng)假的天數(shù)
*/
private int leaveDays;
/**
* 請(qǐng)假人的名字
*/
private String name;
public LeaveRequest leaveDays(int days){
this.leaveDays=days;
return this;
}
public LeaveRequest name(String name){
this.name=name;
return this;
}
public int getLeaveDays() {
return leaveDays;
}
public String getName() {
return name;
}
}
- 具體的使用
public static void main(String[] args){
GManagerHandler gManagerHandler=new GManagerHandler();
DirectLeaderHandler directLeaderHandler=new DirectLeaderHandler();
DeptManagerHandler deptManagerHandler=new DeptManagerHandler();
deptManagerHandler.setNextHandler(gManagerHandler);
directLeaderHandler.setNextHandler(deptManagerHandler);
LeaveRequest request=new LeaveRequest().leaveDays(18).name("小明");
System.out.println(request.getName()+"發(fā)起請(qǐng)"+request.getLeaveDays()+"天假的申請(qǐng)");
directLeaderHandler.handlerRequest(request);
LeaveRequest request2=new LeaveRequest().leaveDays(1).name("小紅");
System.out.println(request2.getName()+"發(fā)起請(qǐng)"+request2.getLeaveDays()+"天假的申請(qǐng)");
directLeaderHandler.handlerRequest(request2);
LeaveRequest request3=new LeaveRequest().leaveDays(2).name("小亮");
System.out.println(request3.getName()+"發(fā)起請(qǐng)"+request3.getLeaveDays()+"天假的申請(qǐng)");
directLeaderHandler.handlerRequest(request3);
}
結(jié)果:
小明發(fā)起請(qǐng)18天假的申請(qǐng)
部門(mén)主管:已審批 還需要部門(mén)經(jīng)理審批
部門(mén)經(jīng)理:已審批 還需要總經(jīng)理審批
總經(jīng)理:已審批 請(qǐng)假申請(qǐng)通過(guò)
小紅發(fā)起請(qǐng)1天假的申請(qǐng)
部門(mén)主管:已審批 請(qǐng)假申請(qǐng)通過(guò)
小亮發(fā)起請(qǐng)2天假的申請(qǐng)
部門(mén)主管:已審批 還需要部門(mén)經(jīng)理審批
部門(mén)經(jīng)理:已審批 請(qǐng)假申請(qǐng)通過(guò)