0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

接单流程设计探索

京东云 来源:京东物流 吕顺 作者:京东物流 吕顺 2024-10-31 10:56 次阅读

作者:京东物流 吕顺

背景

在物流系统中,接单是信息流的关键和重要的一环,每个业务场景都会对应一种标准接单流程,例如销售出、采购入等等。标准接单包括统一接口定义、统一数据模型、标准接单核心应用职责划分。而这个标准并不是在接口定义的初期就规划好的,通常会经历业务不断增长而带来的需求迭代、业务融合、组织架构调整或升级引起的流程优化与拆分。这样一些系列事件下来,可能一个接单应用会流转到多个部门,接单流程就会越来越丰富,可能包括多业务、多场景、个性化、各种开关、五花八门的扩展实现。



问题

在大接入背景下,我们聚焦在一个接单应用的一个接单方法上。或多或少在工作中都会遇到一下几种问题:

•瀑布式迭代,一个方法最终三五千行,难以阅读理解,牵一发动全身。

•大量个性化逻辑散落在下单得每个环节,梳理起来无从下手。

•方法串联时上下文样式各异,如果当初没有扩展性,后期改动变动大。



思路

针对这些问题,可以分为两个层面思考,战略和战术。

战略

这里的战略指的是模式,而接单场景可以利用工作台模式,工人(组件)按顺序围着工作台(上下文)生产两件(执行任务),资源(参数)从工作台拿取,这种模式可以做到组件解耦、稳定、可复用。保证业务流程灵活。

战术

围绕着工作台模式,可以提炼的一下几个关键点:

•组件定义

•上下文

•执行规则



组件定义

组件通常被定义为规则执行的最小单元,我们最常见的是普通组件,也就是调用就执行,这是大部分系统目前都在使用的组件。其实在流程规则中,组件就像编译语言,还应该具备布尔组件、条件组件、循环组件、并行组件、异常捕获组件等等。由于这些组件都可以包含在普通组件中,通过代码来实现条件、循环等逻辑。所以在执行流程定义时,无法清晰识别这些本应体现在流程中的逻辑。



组件定义通常还有一个值得关注的就是组件的数量,哪些逻辑可以归类到一个组件中,哪些需要分开。这里没有标准答案,有两个思路仅供参考:

1.如果订单已经归类不同子域,例如发货、收货、承运、产品、货品等,那就按照对应子域划分组件。这样更容易达成语言统一。

2.根据流程中写动作来定义组件,例如写库、下发wms、下配等。

上下文

在组件定义的时候都会定义上下文作为执行流程中出入参的载体。上下文得定义通常需要具备几个特点:

•传递性

•共享性

•动态性

每个组件都只关心上下文中与自己相关的内容,可以进行读取和更新,然后在流程中不断传递下去。并且在需求迭代过程中支持扩展上下文。



执行规则

执行规则就是约定各种组件按照何种规则执行。这里实现方式大多xml方式、Spring注入方式、显示组装方式成执行链,然后顺序执行。这种方案弊端就是无法体现条件判断、循环、并行。另一个问题就是大家深受SpringBoot思维的“毒害”:约定大于配置,而逐渐放弃xml配置方式,让执行链组装藏在代码中。让执行规则更加不容易被发现,说白了就是执行规则没有与代码进行解耦。那么如果将执行规则单独抽象出来,就可以更进一步支持多种方式存储,例如数据库、redis、ducc等,这样热更就会成为可能。



答案

在不断实践和学习中,我发现了一个具备上述所有能力的开源组件LiteFlow

利用LiteFlow,你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构,这种结构的好处是可以任意编排,组件与组件之间是解耦的,组件可以用脚本来定义,组件之间的流转全靠规则来驱动。LiteFlow拥有开源规则引擎最为简单的DSL语法。十分钟就可上手。









例子

要实现下面的流程:





流程规则:

< ?xml version="1.0" encoding="UTF-8"? >
< 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.java

8 directories, 21 files


业务类型判断:

@LiteflowComponent("businessSwitch")
public class BusinessSwitchCmp extends NodeSwitchComponent {
    @Override
    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();
        }
    }
}

迭代器组件:

@LiteflowComponent("goodsIterator")
public class GoodsIteratorCmp extends NodeIteratorComponent {
    @Override
    public Iterator< Goods > processIterator() throws Exception {
        Request requestData = this.getRequestData();
        return requestData.getGoodList().iterator();
    }
}

循环执行:

@Slf4j
@LiteflowComponent("goodsItem")
public class GoodsItemCmp extends NodeComponent {
    @Override
    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框架都支持。

规则轻量: 基于规则文件来编排流程,学习规则门槛低



总结

LiteFlow是强大的流程规则框架,之所以没有直接把LiteFlow放在标题中,是跟大家一起透过问题看本质,最终找到合适的解决方案,而LiteFlow通过设计和抽象能力解决问题,更加值得借鉴和学习。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 组件
    +关注

    关注

    1

    文章

    503

    浏览量

    17782
  • 物流系统
    +关注

    关注

    0

    文章

    25

    浏览量

    10687
收藏 人收藏

    评论

    相关推荐

    接单片机工作

    诚信尽责,承接单片机工作,或兼职。如需合作,请联系 QQ : 1513306473 。8、16、32位单片机开发上位机开发
    发表于 08-23 11:18

    USB转串口电路原理图怎么接单片机?

    USB转串口电路原理图中怎么接单片机?不明白,请说明下,谢谢!如上图
    发表于 11-17 22:12

    接单片机开发 毕业设计

    接单片机开发QQ:623145061
    发表于 04-14 20:34

    PSoC 4试用+探索

    入门。Cypress也把对芯片底层的一些繁琐重复的工作进行了封装,自动产生了很多的代码。个人觉得这也会使使用者丢失对整体流程的掌握,在出现bug时不容易定位。以上是自己对今晚探索的总结,明天继续。
    发表于 10-30 23:22

    接单片机项目!

    本人承接单片机项目、毕业设计、仿真,私聊1002925094
    发表于 12-13 12:09

    外推接单yilong

    yilong接单,QQ:1728369763。承接:外推(按效果计费)、营销神器注册群发(顶帖)规则定制、易语言软件群发定制、百度百科、百度知道(提问加采纳)、删负面、***(永久版)、新闻源(各大
    发表于 01-30 16:05

    接单片机项目

    接单片机项目、Arduino、Proteus仿真等。有需要详聊 1002925094,非诚勿扰!
    发表于 10-23 21:26

    紧急呼叫单元和无线连接单元介绍

    紧急呼叫单元和无线连接单
    发表于 12-23 06:29

    OpenHarmony终端智能设备开发实现流程探索

    一、简要说明虽然我们还没有做出一款完整的OpenHarmony的终端智能设备,但是在各个维度都有进行一些初步探索尝试。现归纳整体流程如下,不一定正确,欢迎大家讨论与指正。二、整体图示三、详细说明1.
    发表于 08-16 14:42

    Agent Technologies实现应用流程再造

    论文旨在研究自助服务系统应用流程再造的设计与实现,并探索Agent 技术在其中的应用。关键词:Agent;流程再造;业务无关性;
    发表于 06-01 11:04 6次下载

    CH452与4线接口连接单片机电路

    CH452与4线接口连接单片机电路 U2
    发表于 01-07 12:28 2237次阅读
    CH452与4线接口连<b class='flag-5'>接单</b>片机电路

    国巨宣布将停止芯片电阻接单 芯片电阻涨价箭在弦上

    近日,芯片电阻龙头国巨旗下的国益宣布停止芯片电阻接单。业界人士认为国益停止接单,将会影响芯片电阻供应量下降,势必会出现巨大的缺口,涨价已成定局。国益却表示因市场需求已经过大,为了平衡交货服务水平将暂时停止接单,恢复正常
    发表于 12-27 15:19 1808次阅读

    旺宏接单报捷 NOR Flash获ST采用

    旺宏接单报捷,旗下编码型快闪存储器( NOR Flash)获意法半导体(STM)新款微控制器采用,导入汽车、工业及消费电子等领域。
    发表于 03-30 11:14 1062次阅读

    义隆:年后MCU产品全面暂停接单

    据台媒报道,包括义隆、盛群、凌通等在内的 MCU厂商又掀起了新一轮的涨价潮,除再次涨价外,还传出了要求先收订金才能下单,甚至暂停接单的消息 。
    的头像 发表于 02-24 16:31 2536次阅读

    华秋PCB、SMT等业务暂不受疫情影响,正常接单发货!

    一华秋业务不受影响,正常接单发货按深圳最新疫情防控要求,企业3月14至20号居家办公,华秋整体业务不受影响,24小时在线服务,请广大新老用户放心:华秋PCB打样正常接单、SMT打样及小中批量、钢网等
    的头像 发表于 03-15 10:03 947次阅读
    华秋PCB、SMT等业务暂不受疫情影响,正常<b class='flag-5'>接单</b>发货!