前言
做电子政务的项目时,经常会有大量的业务逻辑变更,但其实里面的业务改动,其实就是一些业务逻辑变动。
而程序员编写的代码也没有任何技术含量,跟着式样书逐字逐句的翻译就行。大量的 if/else
判断遍布整个项目,维护难度极大。
而这个 solon-flow 流引擎,可以方便的将业务的整体逻辑移出,更加方便程序的可读性。
准备
第一步 随便建个 maven 项目
第二步 添加 solon-flow 依赖
<dependency><groupId>org.noear</groupId><artifactId>solon-flow</artifactId><version>3.0.7</version>
</dependency>
第三步 在 src\main\resources\flow
下面添加规则文件,规则文件可以是 json 或者 yml 结尾(这里用 yml 格式,简明些)
案例一
先创建个实体类:
public class Order {private Double originalPrice;//订单原始价格,即优惠前价格private Double realPrice;//订单真实价格,即优惠后价格public String toString() {return "Order{" + "originalPrice=" + originalPrice + ", realPrice=" + realPrice + '}';}public Double getOriginalPrice() {return originalPrice;}public void setOriginalPrice(Double originalPrice) {this.originalPrice = originalPrice;}public Double getRealPrice() {return realPrice;}public void setRealPrice(Double realPrice) {this.realPrice = realPrice;}
}
创建 bookDiscount.yml 文件,建立相应处理链(或者规则链)。链有3个节点, start 和 end 表示链条的开头与结尾,book_discount_1 为规则执行节点:
id: "book_discount"
nodes:- type: "start"- id: "book_discount_1"when: "order.getOriginalPrice() < 100"task: |order.setRealPrice(order.getOriginalPrice());System.out.println("没有优惠");- type: "end"
@Test
public void case1() throws Throwable {FlowEngine flowEngine = FlowEngine.newInstance();flowEngine.load(Chain.parseByUri("classpath:flow/bookDiscount.yml"));BookOrder bookOrder = new BookOrder();bookOrder.setOriginalPrice(10);ChainContext ctx = new ChainContext();ctx.put("order", bookOrder);flowEngine.eval("book_discount", ctx);//价格没变,还是10块assert bookOrder.getRealPrice() == 10;
}
单测运行结果:
没有优惠
案例二
在原来的处理链上,添加新的规则
id: "book_discount"
nodes:- type: "start"- id: "book_discount_1"when: "order.getOriginalPrice() < 100"task: |order.setRealPrice(order.getOriginalPrice());System.out.println("没有优惠");- id: "book_discount_4"when: "order.getOriginalPrice() >= 300"task: |order.setRealPrice(order.getOriginalPrice() - 100);System.out.println("优惠100元");- id: "book_discount_2"when: "order.getOriginalPrice() < 200 && order.getOriginalPrice() > 100"task: |order.setRealPrice(order.getOriginalPrice() - 20);System.out.println("优惠20元");- type: "end"
流处理示意图:
单测参考:
@Test
public void case4() throws Throwable {FlowEngine flowEngine = FlowEngine.newInstance();flowEngine.load(Chain.parseByUri("classpath:flow/bookDiscount.yml"));BookOrder bookOrder = new BookOrder();bookOrder.setOriginalPrice(500);ChainContext ctx = new ChainContext();ctx.put("order", bookOrder);flowEngine.eval("book_discount", ctx);//价格变了,省了100块assert bookOrder.getRealPrice() == 400;
}@Test
public void case2() throws Throwable {FlowEngine flowEngine = FlowEngine.newInstance();flowEngine.load(Chain.parseByUri("classpath:flow/bookDiscount.yml"));BookOrder bookOrder = new BookOrder();bookOrder.setOriginalPrice(120);ChainContext ctx = new ChainContext();ctx.put("order", bookOrder);flowEngine.eval("book_discount", ctx);//省了20块assert bookOrder.getRealPrice() == 100;
}
内置脚本能力说明
- when,使用 java 完整语法的表达式,可以直接使用链上下文的模型变量,要求返回布尔值
- task,使用 java 完整语法的代码块,可以直接使用链上下文的模型变量
更多 solon-flow 的说明,可参考 solon-flow 官网资料。