定義:使多個對象都有機會處理請求,從而避免了請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它為止。
類型:行為類模式
類圖:
責任連模式的結構
責任連模式的類圖非常簡單,它由一個抽象地處理類和它的一組實現類組成:
- 抽象處理類:抽象處理類中主要包含一個指向下一處理類的成員變量nextHandler和一個處理請求的方法handRequest,handRequest方法的主要主要思想是,如果滿足處理的條件,則有本處理類來進行處理,否則由nextHandler來處理。
- 具體處理類:具體處理類主要是對具體的處理邏輯和處理的適用條件進行實現。
適用場景:
1、有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定;
2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求;
3、處理一個請求的對象集合應被動態指定。
在職責鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織鏈和分配責任。
在大學里面當班干部,時常要向上級申請各方面的東西。譬如申請全班外出秋游,普通同學將申請表交給班長,班長簽字之后交給輔導員,輔導員批准之后上交到主任辦公室…就是這樣,一個請求(這里是一份申請表)有時候需要經過好幾個級別的處理者(這里是輔導員、主任)的審查才能夠最終被確定可行與否。
在這里表現出來的是一個職責鏈,即不同的處理者對同一個請求可能擔負着不同的處理方式、權限,但是我們希望這個請求必須到達最終拍板的處理者(否則秋游就沒戲了)。這種關系就很適合使用職責鏈模式了。
代碼實現如下:
- // 全局變量,接口類型
- /**
- * 使用Java中的interface定義全局變量,可根據具體需要在
- * 具體的包中使用靜態導入相關的全局變量,語法如下:
- * import static package01.package02.*;
- */
- interface Levels {
- public static final int LEVEL_01 = 1;
- public static final int LEVEL_02 = 2;
- public static final int LEVEL_03 = 3;
- }
- // 抽象請求類
- abstract class AbstractRequest {
- private String content = null;
- public AbstractRequest(String content) {
- this.content = content;
- }
- public String getContent() {
- return this.content;
- }
- // 獲得請求的級別
- public abstract int getRequestLevel();
- }
- // 具體請求類01
- class Request01 extends AbstractRequest {
- public Request01(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_01;
- }
- }
- // 具體請求類02
- class Request02 extends AbstractRequest {
- public Request02(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_02;
- }
- }
- // 具體請求類03
- class Request03 extends AbstractRequest {
- public Request03(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_03;
- }
- }
- // 抽象處理者類,
- abstract class AbstractHandler {
- // 責任鏈的下一個節點,即處理者
- private AbstractHandler nextHandler = null;
- // 捕獲具體請求並進行處理,或是將請求傳遞到責任鏈的下一級別
- public final void handleRequest(AbstractRequest request) {
- // 若該請求與當前處理者的級別層次相對應,則由自己進行處理
- if (this.getHandlerLevel() == request.getRequestLevel()) {
- this.handle(request);
- } else {
- // 當前處理者不能勝任,則傳遞至職責鏈的下一節點
- if (this.nextHandler != null) {
- System.out.println("當前 處理者-0" + this.getHandlerLevel()
- + " 不足以處理 請求-0" + request.getRequestLevel());
- // 這里使用了遞歸調用
- this.nextHandler.handleRequest(request);
- } else {
- System.out.println("職責鏈上的所有處理者都不能勝任該請求...");
- }
- }
- }
- // 設置責任鏈中的下一個處理者
- public void setNextHandler(AbstractHandler nextHandler) {
- this.nextHandler = nextHandler;
- }
- // 獲取當前處理者的級別
- protected abstract int getHandlerLevel();
- // 定義鏈中每個處理者具體的處理方式
- protected abstract void handle(AbstractRequest request);
- }
- // 具體處理者-01
- class Handler01 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_01;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-01 處理 " + request.getContent() + "\n");
- }
- }
- // 具體處理者-02
- class Handler02 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_02;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-02 處理 " + request.getContent()+ "\n");
- }
- }
- // 具體處理者-03
- class Handler03 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_03;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-03 處理 " + request.getContent()+ "\n");
- }
- }
- // 測試類
- public class Client {
- public static void main(String[] args) {
- // 創建指責鏈的所有節點
- AbstractHandler handler01 = new Handler01();
- AbstractHandler handler02 = new Handler02();
- AbstractHandler handler03 = new Handler03();
- // 進行鏈的組裝,即頭尾相連,一層套一層
- handler01.setNextHandler(handler02);
- handler02.setNextHandler(handler03);
- // 創建請求並提交到指責鏈中進行處理
- AbstractRequest request01 = new Request01("請求-01");
- AbstractRequest request02 = new Request02("請求-02");
- AbstractRequest request03 = new Request03("請求-03");
- // 每次提交都是從鏈頭開始遍歷
- handler01.handleRequest(request01);
- handler01.handleRequest(request02);
- handler01.handleRequest(request03);
- }
- }
測試結果:
- 處理者-01 處理 請求-01
- 當前 處理者-01 不足以處理 請求-02
- 處理者-02 處理 請求-02
- 當前 處理者-01 不足以處理 請求-03
- 當前 處理者-02 不足以處理 請求-03
- 處理者-03 處理 請求-03
1、對於每一個請求都需要遍歷職責鏈,性能是個問題;
2、抽象處理者 AbstractHandler 類中的 handleRequest() 方法中使用了遞歸,棧空間的大小也是個問題。
參考:http://blog.csdn.net/zhengzhb/article/details/7568676
http://haolloyin.blog.51cto.com/1177454/342166/
http://blog.csdn.net/qq7342272/article/details/6921524
http://blog.csdn.net/hguisu/article/details/7547231
http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
http://www.cnblogs.com/xudong-bupt/p/3617860.html