一、概述
避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿着這條鏈傳遞請求,直到有對象處理它爲止。職責鏈模式是一種對象行爲型模式。
核心在於引入一個抽象處理者類
二、適用場景
請求的鏈式處理,多個對象可以處理同一請求、但是具體由哪個對象來處理由運行時系統根據條件判斷確定。
如請假業務場景:
三、UML類圖
四、參與者
1、Handler(抽象處理者):它定義了一個處理請求的接口,一般設計爲抽象類,由於不同的具體處理者處理請求的方式不同,因此在其中定義了抽象請求處理方法。因爲每一個處理者的下家還是一個處理者,因此在抽象處理者中定義了一個抽象處理者類型的對象(如結構圖中的nextHandler),作爲其對下家的引用。通過該引用,處理者可以連成一條鏈。
2、ConcreteHandler(具體處理者):它是抽象處理者的子類,可以處理用戶請求,在具體處理者類中實現了抽象處理者中定義的抽象請求處理方法,在處理請求之前需要進行判斷,看是否有相應的處理權限,如果可以處理請求就處理它,否則將請求轉發給後繼者;在具體處理者中可以訪問鏈中下一個對象,以便請求的轉發。
注意:職責鏈模式並不創建職責鏈,職責鏈的創建工作必須由系統的其他部分來完成,一般是在使用該職責鏈的客戶端中創建職責鏈。
五、用例學習
1、抽象處理者類:Handler.java
/**
* 抽象處理者類
* @author [email protected]
*
*/
public abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler){
this.nextHandler = nextHandler;
}
public abstract void handleRequest(int request);
}
2、具體處理者類A:部門組長 ConcreteHandlerA.java
/**
* 具體職責處理者A:案例中的 部門組長角色
* @author [email protected]
*
*/
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int leaveDay) {
if(leaveDay <= 1){
// 滿足處理條件 處理請求
System.out.println("請假天數小於2天 由部門組長審批");
} else {
nextHandler.handleRequest(leaveDay);
}
}
}
3、具體處理者類B:部門經理 ConcreteHandlerB.java
/**
* 具體職責處理者B:案例中的 部門經理角色
* @author [email protected]
*
*/
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int leaveDay) {
if(1 < leaveDay && leaveDay <= 5){
// 滿足處理條件 處理請求
System.out.println("請假天數大於1天且小於等於5天 由部門經理審批");
} else {
nextHandler.handleRequest(leaveDay);
}
}
}
4、具體處理者類C:總經理 ConcreteHandlerC.java
/**
* 具體職責處理者C:案例中的 總經理角色
* @author [email protected]
*
*/
public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int leaveDay) {
if(leaveDay > 5){
System.out.println("當請假天數大於5天的情況下 由總經理親自操刀審批。總經理的職責已經是最大的啦,還有他沒有權限處理的事嗎?");
}
}
}
5、客戶端類:Client.java
/**
* 客戶端類<br/>
* 負責創建職責鏈和發送請求<br/>
* 當職責鏈(職責的傳遞順序/請求的處理順序)建好之後,客戶端只負責將請求發送出去,
* 而具體請求在職責鏈上的傳遞和最終由鏈上的哪個對象進行處理不由客戶端關心
* @author [email protected]
*
*/
public class Client {
public static void main(String[] args) {
Handler handlerA,handlerB,handlerC;
handlerA = new ConcreteHandlerA();
handlerB = new ConcreteHandlerB();
handlerC = new ConcreteHandlerC();
// 創建職責鏈 handlerA ——> handlerB ——> handlerC
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
// 發送請假請求一
handlerA.handleRequest(1);
// 發送請假請求二
handlerA.handleRequest(7);
// 發送請假請求二
handlerA.handleRequest(3);
}
}
6、運行結果:
請假天數小於2天 由部門組長審批
當請假天數大於5天的情況下 由總經理親自操刀審批。總經理的職責已經是最大的啦,還有他沒有權限處理的事嗎?
請假天數大於1天且小於等於5天 由部門經理審批