背景
问题
•瀑布式迭代,一个方法最终三五千行,难以阅读理解,牵一发动全身。
•大量个性化逻辑散落在下单得每个环节,梳理起来无从下手。
•方法串联时上下文样式各异,如果当初没有扩展性,后期改动变动大。
思路
针对这些问题,可以分为两个层面思考,战略和战术。
战略
这里的战略指的是模式,而接单场景可以利用工作台模式,工人(组件)按顺序围着工作台(上下文)生产两件(执行任务),资源(参数)从工作台拿取,这种模式可以做到组件解耦、稳定、可复用。保证业务流程灵活。
战术
围绕着工作台模式,可以提炼的一下几个关键点:
•组件定义
•上下文
•执行规则
组件定义
1.如果订单已经归类不同子域,例如发货、收货、承运、产品、货品等,那就按照对应子域划分组件。这样更容易达成语言统一。
2.根据流程中写动作来定义组件,例如写库、下发wms、下配等。
上下文
在组件定义的时候都会定义上下文作为执行流程中出入参的载体。上下文得定义通常需要具备几个特点:
•传递性
•共享性
•动态性
每个组件都只关心上下文中与自己相关的内容,可以进行读取和更新,然后在流程中不断传递下去。并且在需求迭代过程中支持扩展上下文。
执行规则
答案

例子
要实现下面的流程:
流程规则:
<flow><chain name="chain1">THEN(SWITCH(businessSwitch).TO(// 中小件子流程THEN(smallChain).id("small"),// 冷链子流程THEN(coldChain).id("cold")),// 迭代执行ITERATOR(goodsIterator).DO(goodsItem),// 选择器+默认SWITCH(kaSwitch).TO(dajiang, lining, nike).DEFAULT(defaultKa));</chain><chain name="smallChain">// 并行WHEN(commonDept, smallWarehouse);</chain><chain name="coldChain">// 并行WHEN(commonDept, coldWarehouse);</chain></flow>
代码结构:
.├── LiteFlowDemoApplication.java└── demos└── web├── BasicController.java├── context│ └── OrderContext.java├── dto│ ├── Dept.java│ ├── Goods.java│ ├── Request.java│ └── WareHouse.java├── enums│ ├── BusinessEnum.java│ └── KaEnum.java└── node├── BusinessSwitchCmp.java├── ColdWarehouseCmp.java├── CommonDeptCmp.java├── GoodsItemCmp.java├── GoodsIteratorCmp.java├── KaSwitchCmp.java├── SmallWarehouseCmp.java└── ka├── DaJiangCmp.java├── DefaultCmp.java├── LiNingCmp.java└── NikeCmp.java8 directories, 21 files
业务类型判断:
("businessSwitch")public class BusinessSwitchCmp extends NodeSwitchComponent {public String processSwitch() throws Exception {Request request = this.getRequestData();if(Objects.equals(request.getDept().getDeptNo(), "dept1")) {return BusinessEnum.SMALL.getBusiness();} else {return BusinessEnum.COLD.getBusiness();}}}
迭代器组件:
("goodsIterator")public class GoodsIteratorCmp extends NodeIteratorComponent {public Iterator<Goods> processIterator() throws Exception {Request requestData = this.getRequestData();return requestData.getGoodList().iterator();}}
循环执行:
public class GoodsItemCmp extends NodeComponent {public void process() throws Exception {log.info("goods item index = {}", this.getLoopIndex());//获取当前循环对象Goods goods = this.getCurrLoopObj();//赋值为当前循环索引goods.setGoodsId(this.getLoopIndex());OrderContext orderContext = this.getContextBean(OrderContext.class);List<Goods> goodsList = orderContext.getData("goods");if(goodsList == null) {goodsList = new ArrayList<>();this.getContextBean(OrderContext.class).setData("goods", goodsList);}goodsList.add(goods);}}
测试用例
public String testConfig() {Request request = new Request();Dept dept = new Dept();dept.setDeptNo("nike");request.setDept(dept);WareHouse wareHouse = new WareHouse();request.setWareHouse(wareHouse);Goods goods1 = new Goods();goods1.setGoodsName("goods1");Goods goods2 = new Goods();goods2.setGoodsName("goods2");request.setGoodList(Arrays.asList(goods1, goods2));//参数1为流程标识,参数2为初始入参,参数3为上下文类型约定LiteflowResponse liteflowResponse = flowExecutor.execute2Resp("chain1",request, OrderContext.class);//结果中获取上下文OrderContext contextBean = liteflowResponse.getContextBean(OrderContext.class);List<Goods> goodsList = contextBean.getData("goods");WareHouse warehouse = contextBean.getData("warehouse");Dept dept1 = contextBean.getData("dept");log.info("=== dept = {}", JsonUtil.toJsonString(dept1));log.info("=== warehouse = {}", JsonUtil.toJsonString(warehouse));log.info("=== goodsList = {}", JsonUtil.toJsonString(goodsList));return "yes";}
特点
个人觉得LiteFlow的特点包括一下几点:
-
组件定义统一:所有的逻辑都是组件,为所有的逻辑提供统一化的组件实现方式 -
规则持久化:框架原生支持把规则存储在标准结构化数据库,Nacos,Etcd,Zookeeper,Apollo,Redis、自定义扩展。 -
上下文隔离机制:可靠的上下文隔离机制,无需担心高并发情况下的数据串流 -
支持广泛:Springboot,Spring还是任何其他java框架都支持。 -
规则轻量:基于规则文件来编排流程,学习规则门槛低
总结
扫一扫,加入技术交流群


