14 責任鏈模式

定義

責任鏈模式(Chain of Responsibility Pattern):避免將一個請求的發送者與接受者耦合在一起,讓對個對象都有機會處理請求。將接受者的對象連接成一條鏈,並且沿着這條鏈傳遞請求,直到有一個對象能夠處理它爲止。

結構

  1. Handler(抽象處理者):它定義了一個處理請求的接口,一般設計爲抽象類,由於不同的具體處理者處理請求的方式不同,因此在其中定義了一個抽象請求處理方法。每一個處理這的下家還是一個處理者,故在抽象處理者中定義了一個抽象處理者類型對象作爲其對下家的引用,通過該引用處理者可以連成提條鏈。
  2. ConcreteHandler(具體處理者):它是抽象處理者的子類,可以處理用戶請求,在具體處理者類中實現了抽象處理者中定義的抽象請求處理方法,在處理請求之前需要進行判斷,看是否有相應的處理權限,如果可以處理請求就處理它,否則將請求轉發給後繼者;在具體處理者中可以訪問鏈中的下一個對象,以便請求轉發。

代碼

Handler

public abstract class Handler {

    // 維持對下家的引用
    protected Handler successor;

    public abstract void handleRequest(String request);

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
}

ConcreteHandler1

public class ConcreteHandler1 extends Handler {

    @Override
    public void handleRequest(String request) {
        if ("ConcreteHandler1".equals(request)) {
            // 滿足條件,處理請求
            System.out.println("ConcreteHandler1");
        } else {
            // 將請求轉發到下家
            successor.handleRequest(request);
        }
    }

}

ConcreteHandler2

public class ConcreteHandler2 extends Handler {

    @Override
    public void handleRequest(String request) {
        if ("ConcreteHandler2".equals(request)) {
            // 滿足條件,處理請求
            System.out.println("ConcreteHandler2");
        } else {
            // 將請求轉發到下家
            successor.handleRequest(request);
        }
    }

}

ConcreteHandler3

public class ConcreteHandler3 extends Handler {

    @Override
    public void handleRequest(String request) {
        if ("ConcreteHandler3".equals(request)) {
            // 滿足條件,處理請求
            System.out.println("ConcreteHandler3");
        } else {
            // 將請求轉發到下家
            successor.handleRequest(request);
        }
    }

}

Test

public class Test {

    public static void main(String[] args) {
        Handler handler1, handler2, handler3;
        handler1 = new ConcreteHandler1();
        handler2 = new ConcreteHandler2();
        handler3 = new ConcreteHandler3();

        // 創建責任鏈
        handler1.setSuccessor(handler2);
        handler2.setSuccessor(handler3);
        // 發送請求
        handler1.handleRequest("ConcreteHandler2");
    }

}

純與不純的職責鏈模式

  1. 一個純的職責鏈模式要求一個具體處理者對象只能在兩個行爲中選擇一個,要麼承擔全部職責,要麼將責任推給下家,不允許出現某個具體處理者對象在承擔了一部分或全部責任後又將責任向下船體的情況。而且在純的職責鏈模式中要求一個請求必須被某一個處理者對象所接受,不能出現某個請求未被任何一個處理者對象處理的情況。
  2. 在一個不純的職責鏈模式中允許某個請求被一個具體處理者部分處理後再向下傳遞,或者一個具體處理者處理完某請求後其後繼處理者可以繼續處理請求,而且一個請求可以最終不被任何處理者對象所接收並處理。

優/缺點與適用環境

  1. 優點
  • 職責鏈模式使得一個對象無須知道是其他哪一個對象處理其請求,對象僅需知道該請求會被處理即可,接收者和發送者都沒有對象的明確信息,並且鏈中的對象不需要知道鏈的結構,由客戶增負責鏈的創建,降低了系統的耦合度。
  • 請求處理對象僅需維持一個指向其後繼者的引用,而不需要維持它對所有的候選處理者的引用,可簡化對象之間的相互連接。
  • 在給對象分派職責時.職責鏈可以帶來更多的靈話性,可以通過在運行時對該鏈進行動態的增加或修改來增加或改變處理一個請求的職責。
  • 在系統中增加一個新的具體請求處理者時無須修改原有系統的代碼,只需要在客戶端重新建鏈即可,從這一點來看是符合開閉原則的。
  1. 缺點
  • 由於一個請求沒有明確的接收者,那麼就不能保證它一定會被處理,該請求可能一直到鏈的末端都得不到處理;一個請求也可能因職責鏈沒有被正確配置而得不到處理。
  • 對於比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定的影響,而且在進行代碼調試時不太方便。
  • 如果建鏈不當,可能會造成循環調用,將導致系統陷入死循環。
  1. 適用環境
  • 有多個對象可以處理同一個請求,具體哪個對象處理該請求待運行時刻再確定,客戶端只需將請求提交到鏈上,而無須關心請求的處理對象是誰以及它是如何處理的。
  • 在不明確指定接收者的情況下向多個對象中的一個提交一個請求。
  • 可動態指定一組對象處理請求,客戶端可以動態創建職責鏈來處理請求,還可以改變鏈中處理者之間的先後次序。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章