本文链接: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 {
/**
* 平台调用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 扩展点,对应我们案例中的PurchaseOderBuildExt,AlphaPurchaseOderBuildExt,BetaPurchaseOderBuildExt
*/
public class ExtensionAbility {
/**
* 根据bizType执行扩展点
* @param bizType 业务类型
* @param caller lambda表达式的调用者
* @param 扩展点的返回类型
* @return R
*/
public R executeByType(String bizType, ExtensionCaller caller) {
String bizCode = extClass.getName();
return execute(bizCode + bizType, caller);
}
/**
* 根据bizCode执行扩展点
* @param bizCode bizCode
* @param caller caller
* @param R
* @return
*/
public R execute(String bizCode, ExtensionCaller 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 extClass;
public ExtensionAbility() {
//获取扩展点的类名
Type type = getClass().getGenericSuperclass();
Type trueType = ((ParameterizedType) type).getActualTypeArguments()[0];
this.extClass = (Class) 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