本文鏈接: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