運用lambda表達式+策略模式實現平臺業務擴展

本文鏈接:https://blog.csdn.net/lightj1996/article/details/103656673

源碼地址:https://download.csdn.net/download/lightj1996/12046339

初衷:

        很多時候,我們開發的平臺會被很多業務方所接入。比如,給銀行開發的金融系統,可能不同的子銀行有自己的需求。我們希望我們平臺和業務能夠分離,平臺的邏輯不感知業務。就好比,平臺是一個槽,不同的業務想要接入,就以插件的形式進行插入。

策略模式:

        實現不同業務之間業務的分離,我們想到最好的設計模式是策略模式。比如,我們平臺接入方有兩個:一個叫 alpha,一個叫deta。當alpha登錄時,會在Session中放置bizType = "alpha", 當beta登錄時,會在Session中放置bizType = "beta"。這裏的bizType其實就是策略模式的策略碼,現在我們實現兩種策略的buildPurchaseOrder。

代碼:

        //模擬平臺當前登錄Session的bizType爲alpha
        TestSession.getInstance().setBizType("alpha");
        purchaseOderBuildAbility.buildPurchaseOrder();
        //模擬平臺當前登錄Session的bizType爲beta
        TestSession.getInstance().setBizType("beta");
        purchaseOderBuildAbility.buildPurchaseOrder();
        //模擬平臺當前登錄Session的bizType爲default
        TestSession.getInstance().setBizType("default");
        purchaseOderBuildAbility.buildPurchaseOrder();

運行結果

結果我們看到不同的業務登錄會調用其不同策略的方法。

我們接下來看  purchaseOderBuildAbility.buildPurchaseOrder(); 這個方法


/**
 * PurchaseOderBuildPoint 構建PurchaseOder的擴展的擴展點。
 */
public class PurchaseOderBuildAbility extends ExtensionAbility<PurchaseOderBuildPoint> {
    /**
     * 平臺調用buildPurchaseOrder
     */
    public PurchaseOrder buildPurchaseOrder() {
        // 根據策略碼執行 buildPurchaseOrder
        return executeByType(getBizTypeFromSession(), extension -> extension.buildPurchaseOrder(new PurchaseOrder()));
    }
    /**
     * 從Session中獲取 BizType
     * @return
     */
    private String getBizTypeFromSession() {
        return TestSession.getInstance().getBizType();
    }
}

 

PurchaseOderBuildPoint我們可以抽象的稱之爲 PurchaseOder的擴展點。他有三個實現:

AlphaPurchaseOderBuildExt, BetaPurchaseOderBuildExt,以及默認的PurchaseOderBuildExt。

lambda表達 extension -> extension.buildPurchaseOrder(new PurchaseOrder()  就是擴展點的運行

bizType = "alpha"時    運行如下代碼

bizType = "bata"時    運行如下代碼

bizType = "default"時    運行如下代碼

我們看到使用一個lamda表達式,和一個策略碼就能實現對不同業務的擴展。是不是很抽象?接下來我們看怎麼實現?

能力:

PurchaseOderBuildAbility 我們稱他爲 構建PurchaseOder的能力,他繼承了 ExtensionAbility

/**
 * ExtensionAbility 擴展點能力
 * @param <T> 擴展點,對應我們案例中的PurchaseOderBuildExt,AlphaPurchaseOderBuildExt,BetaPurchaseOderBuildExt
 */
public class ExtensionAbility<T extends ExtensionPoint> {
    /**
     * 根據bizType執行擴展點
     * @param bizType 業務類型
     * @param caller lambda表達式的調用者
     * @param <R> 擴展點的返回類型
     * @return R
     */
    public <R> R executeByType(String bizType, ExtensionCaller<T, R> caller) {
        String bizCode = extClass.getName();
        return execute(bizCode + bizType, caller);
    }
    /**
     * 根據bizCode執行擴展點
     * @param bizCode bizCode
     * @param caller caller
     * @param <R> R
     * @return
     */
    public  <R> R execute(String bizCode, ExtensionCaller<T, R> caller) {
        T extension = this.getExtensionPoint(bizCode);
        return caller.call(extension);
    }
    /**
     * 根據獲取擴展點
     * @param bizCode 實際上bizCode = bizCode + bizType;
     * @return 具體的擴展點
     */
    private T getExtensionPoint(String bizCode) {
        return (T)ExtensionBuilder.getInstance().getExtensionPint(bizCode);
    }
    /**
     * 擴展點的類
     */
    private Class<T> extClass;
    public ExtensionAbility() {
        //獲取擴展點的類名
        Type type = getClass().getGenericSuperclass();
        Type trueType = ((ParameterizedType) type).getActualTypeArguments()[0];
        this.extClass = (Class<T>) trueType;
    }
    /**
     * 獲取BizCode 這裏BizCode就是對於擴展點類名,其實BizCode+BizType才組合成一個策略碼,
     * 一個業務下面會有很多擴展點,我們不止要對PurchaseOderBuildPoint進行擴展,
     * BizCode這裏的對應案例是PurchaseOderBuildPoint
     * @return BizCode
     */
    public String getBizCode() {
        return extClass.getName();
    }
}

這裏纔是我們代碼核心的地方,我們在工程啓動的時候,會將bizType->Extension的映射放入一個Map(如何構建這個map,大家可以下載我的代碼進行閱讀,這裏只介紹的核心部分),具體到用的時候,只需要找到對應的能力,並從會話中獲取BizType就可以執行不同業務的擴展。我們還可以將不同的業務擴展代碼已jar包的形式進行插入。這個後續會給大家詳細介紹。

 

本文原創,如若轉載請註明出處https://blog.csdn.net/lightj1996/article/details/103656673

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章