简介
Lattice 是一个强大的、轻量级的,面向业务定制高可扩展的业务管理框架。通过使用 Lattice 框架,可以对复杂的业务定制进行高效的组织与管理。这个框架的关键设计要点:
业务/平台分离插件化架构: 平台提供插件包注册机制,实现业务方插件包在运行期的注册。业务代码只允许存在于插件包中,与平台代码严格分离。业务包的代码配置库也与平台的代码库分离,通过二方包的方式,提供给容器加载。
统一业务身份: 平台需要能有按“业务身份”进行业务与业务之间逻辑隔离的能力,而不是传统 SPI 架构不区分业务身份,简单过滤的方式。如何设计这个业务身份,也成为业务与业务之间隔离架构的关键。
管理域与运行域分离: 业务逻辑不能依靠运行期动态计算,要能在静态期进行定义并可视化呈现。业务定义中出现的规则叠加冲突,也在静态器进行冲突决策。在运行期,严格按照静态器定义的业务规则、冲突决策策略执行。Lattice 项目地址:https://github.com/hiforce/lattice
快速开始
版本依赖
<dependency> <groupId>org.hiforce.lattice</groupId> <artifactId>lattice-model</artifactId> <version>1.0.13</version></dependency><dependency> <groupId>org.hiforce.lattice</groupId> <artifactId>lattice-runtime</artifactId> <version>1.0.13</version></dependency>
复制代码
Step 1:定义 “自定义商品单价” 扩展点
定义一个“自定义商品单价”的扩展点,允许业务能够去实现该扩展点,返回商品的自定义单价。
public interface OrderLinePriceExt extends IBusinessExt { String EXT_ORDER_LINE_CUSTOM_UNIT_PRICE = "OrderLinePriceExt.EXT_ORDER_LINE_CUSTOM_UNIT_PRICE";
@Extension( code = EXT_ORDER_LINE_CUSTOM_UNIT_PRICE, name = "Custom the Item's unit price of OrderLine", reduceType = ReduceType.FIRST ) Long getCustomUnitPrice(OrderLine orderLine);}
复制代码
扩展点用 @Extension 注解进行标识,并分配一个全局唯一的扩展点编码,同时申明该扩展点的 Reduce 策略为 FIRST。 (Reduce 策略本章大家参考:https://www.ryu.xin/2022/09/27/lattice-reduce-policy)
Step 2:定义 “子订单价格管理” 能力
@Ability(name = "OrderLine's Price Ability")public class OrderLinePriceAbility extends BaseLatticeAbility<OrderLinePriceExt> { ...... public Long getCustomUnitPrice(OrderLine orderLine) { return Optional.ofNullable(reduceExecute( p -> p.getCustomUnitPrice(orderLine), Reducers.firstOf(Objects::nonNull))) .orElse(orderLine.getUnitPrice()); } ......}
复制代码
能力的定义用 @Ability 注解进行标识,同时需要申明当前的能力管理的扩展点集合是 OrderLinePriceExt。 并且,通过 getDefaultRealization() 方法,提供一个默认实现。
能力通过 reduceExecute () 方法尝试去加载 业务 针对 “自定义商品单价” 扩展点的自定义实现逻辑。
Step 3:编写业务自定义实现逻辑
我们定义一个业务 A,用 @Business 注解标识,并定义该业务的编码为 "business.a",如下:
@Business(code = "business.a", name = "Business A")public class BusinessA extends BusinessTemplate {}
复制代码
然后,针对业务 A,定义它的商品自定义单价为 2000 (单位分)。
@Realization(codes = "business.a")public class BusinessAExt extends BlankOrderLinePriceExt { @Override public Long getCustomUnitPrice(OrderLine orderLine) { return 2000L; }}
复制代码
业务的自定义实现逻辑用 @Realization 标识,并且 业务编码 是 "business.a"
我们可以用类似的方法,再定义一个业务 B,同时业务 B 对商品单价没有做任何定制,如下:
@Business(code = "business.b", name = "Business B")public class BusinessB extends BusinessTemplate {}
@Realization(codes = "business.b")public class BusinessBExt extends BlankOrderLinePriceExt { //do nothing.}
复制代码
Step 4:启动 Lattice,并执行扩展点
public class LatticeQuickStart {
public static void main(String[] args) { Lattice.getInstance().setSimpleMode(true); Lattice.getInstance().start();
doBusinessA(); doBusinessB();
}
private static void doBusinessA() { OrderLine orderLine = new OrderLine(); orderLine.setUnitPrice(1000L); orderLine.setBizCode("business.a"); OrderLinePriceAbility ability = new OrderLinePriceAbility(orderLine); Long unitPrice = ability.getCustomUnitPrice(orderLine); System.out.println("[Business A] unit price: " + unitPrice); }
private static void doBusinessB() { OrderLine orderLine = new OrderLine(); orderLine.setUnitPrice(1000L); orderLine.setBizCode("business.b"); OrderLinePriceAbility ability = new OrderLinePriceAbility(orderLine); Long unitPrice = ability.getCustomUnitPrice(orderLine); System.out.println("[Business B] unit price: " + unitPrice); }}
复制代码
我们分别模拟两次业务调用,其中商品默认单价(数据库中商品发布后的默认价格)为 1000L。 因为业务 A 对商品单价有定制,最终返回值应该是被定制后的 2000L; 而业务 B 没有做任何定制,所以返回值依然应该是 1000L。 运行 org.hiforce.lattice.sample.LatticeQuickStart#main 的控制台打印结果如下:
[Business A] unit price: 2000[Business B] unit price: 1000
复制代码
通以上例子,我们可以看到基于 Lattice 框架最简单的一个用法。通过这种方式,我们可以很好地做到业务定制逻辑插件化,业务定制逻辑与平台隔离。同时,在本样例中,有两个业务,他们的业务身份分别为 "business.a"和"business.b"。通过业务身份,我们进一步让不同业务的定制逻辑进行分离。通过这种方式,可以极大地保护平台代码不被业务定制逻辑侵入,同时业务定制也能做到插件化闭包。
本样例代码:https://github.com/hiforce/lattice-sample/tree/main/lattice-quick-start
评论