《一天一模式》— 責任鏈模式

1、責任鏈模式的概念

責任鏈模式是一種對象的行爲模式。在責任鏈模式裏,不少對象由每個對象對其下家的引用而鏈接起來造成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪個對象最終處理這個請求,這使得系統能夠在不影響客戶端的狀況下動態地從新組織和分配責任。java

2、何時使用責任鏈模式

根據概念理解,責任鏈模式是一種能夠處理一次請求流的一種模式,相似業務工做流程,並且責任鏈能夠動態的調整流程中的各個環節。設計模式

也就是說,若是業務裏有這種須要逐級處理的業務,但是嘗試使用責任鏈模式。測試

我在項目中,通常須要逐級作業務判斷的時候會使用工做流模式,例如:優化

http請求攔截器,先判斷HttpHeader的協議是否正確,在判斷登陸信息是否正確,在判斷請求內容是否正確等,這幾步判斷就能夠用責任鏈模式實現;this

從代碼結構角度,能夠解決嵌套if的問題,例如:spa

if (驗證協議) {
    ....
    if (驗證鑑權) {
        ....
        if (驗證數據) {
            ....
        }
    }
}

能夠避免這種嵌套if結構,提高代碼的可讀性。下面來試着用Java代碼實現責任鏈模式。設計

3、怎麼使用責任鏈模式

3.1 實現方式

就以請求攔截器爲例,模擬作一個責任鏈模式,一共三步驗證:code

  • 驗證協議是否正確;
  • 驗證登陸信息是否正確;
  • 驗證請求數據是否正確;

下面是類圖和代碼:對象

// 責任鏈模式的抽象類
public abstract class Validator {

    // 設置責任鏈的下一個環節
    private Validator next;

    public Validator setNext(Validator next) {
        this.next = next;
        // 返回下一個環節,作到鏈式設置
        return next;
    }

    // 開始責任鏈的處理
    public final void handler(List<String> context) {
        if (!resolve(context)) { // 判斷處理結果是否失敗,若是失敗則不向下進行
            fail(context);
        } else if (next != null) { // 若是本環節處理成功,判斷是否還有下一環節,若是就,就執行下一個環節的handler
            next.handler(context);
        } else { // 若是處理成功,切沒有下一個環節了,責任鏈結束
            success(context);
        }
    }

    // 具體處理業務的方法,定義一個抽象方法等待被子類實現(相似模板方法模式)
    protected abstract boolean resolve(List<String> context);

    // 成功經過的處理
    protected void success(List<String> context) {
        System.out.println("驗證經過。");
    }

    // 未成功經過的處理
    protected void fail(List<String> context) {
        System.out.println("驗證失敗。");
    }

}

// 驗證鑑權的處理類
public class AuthValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(1).equals("admin");
    }
}

// 驗證協議的處理類
public class ProtocolValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(0).equals("http");
    }
}

// 驗證數據的處理類
public class DataSecurityValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(2).equals("hello");
    }
}

上面是責任鏈模式的類圖和代碼,從代碼上看,抽象類定義了責任鏈的建立方法,和循環調用方法,但具體的處理,須要有子類的實現(相似模板方法),而後在成功或者失敗的時候,進行相關處理,責任鏈模式的使用方式以下:blog

public class Client {

    public static void main(String[] args) {

        // 由於是測試,因此在此處配置了責任鏈的關係,正常狀況下,Client是不須要知道責任鏈的配置關係的
        Validator protocolValidator = new ProtocolValidator();
        Validator authValidator = new AuthValidator();
        Validator dataSecurityValidator = new DataSecurityValidator();
        protocolValidator.setNext(authValidator).setNext(dataSecurityValidator);
        // 處理,模擬驗證經過
        List<String> params1 = new ArrayList<String>();
        params1.add("http");
        params1.add("admin");
        params1.add("hello");
        protocolValidator.handler(params1);
        // 處理,模擬驗證失敗
        List<String> params2 = new ArrayList<String>();
        params2.add("http");
        params2.add("ss");
        params2.add("hello");
        protocolValidator.handler(params2);
    }

}

先將幾個環節經過setNext創建起關聯,而後從某個節點(一般是第一個節點)開始調用handler,進行業務的處理。

以上就是責任鏈模式的Java代碼實現。

3.2 責任鏈模式的好處

責任鏈模式的好處以下:

  • 可讀性高:將嵌套判斷的代碼塊用面向對象的方式去優化,經過良好的命名起到語義化的效果;
  • 靈活性強:能夠隨意經過setNext配置各個判斷環節的先後關係,而不須要修改代碼,嵌套if是作不到的;
  • 擴展性強:如後續有需求變動,能夠快讀的加入新的責任鏈環節,而無需修改原有代碼,符合開閉原則;

4、總結

責任鏈模式,面相的業務場景相對比較單一,比較好肯定在什麼業務場景下使用。可是實現的代碼比起其餘的設計模式,稍微複雜了一點,但也比較好理解。

還有就是,責任鏈模式的一個隱藏的優勢是,它弱化了調用者(Client)和處理者(Validator)以前的關聯,調用者其實無需知道責任鏈的每一個環節的關係,只是去調用責任鏈的hanlder方法便可,這種解除耦合的優勢很重要。

以上就是我對責任鏈模式的一些理解,有不足之處請你們指出,謝謝。

相關文章
相關標籤/搜索