WES 重构系列(三):系统融合支持混场业务调度
文内时序图与重构前后对比图需要科学上网才能流畅查看,图床直接用了 GitHub。
一、为什么要做货架到人与料箱到人两套系统的融合?
随着国内和海外仓业务的发展,部分智能仓要求支持货架到人与料箱到人混场调度,我们旧有的 WES 系统是各自独立的,货架到人 WES 只支持货架仓,料箱到人 WES 只支持料箱仓。
出于支持混场调度,我们做了这次融合。
二、系统融合的规划与难点
融合涉及的服务主要是工作站 Station 和 WES。
工作站服务是独立的两套工作流,但业务逻辑有许多共性。比如拣选业务,都要经过实操亮灯、扫码拣选、拍槽位灯、封箱、全部分播完成等步骤,工作流本身支持按业务类型弹实操,这一块相对来说难点不大,主要还是细活,做代码迁移和表迁移,但话说回来,一些细活其实就是工程能力。
WES 这边涉及到的内容多一些:
-
商品库存:二级库存、三级库存、批次、商品、条码、货主、包装、库存流水、库存调整单、库存快照……
-
理货业务:分为货架到人理货和料箱到人理货,理货单、理货单明细、理货下架作业单、理货下架作业单明细、理货下架任务……
-
盘点:也是多种业务,业务对应的表也很多
-
出库:也是多种业务,业务对应的表也很多
-
上架:离线和在线都有许多业务模式,对应的表也有许多
如果只是实现混场业务调度的目的,粗糙地做也能做,但还是想做一些优化,思考几个问题:
-
货架到人与料箱到人业务有许多相似点,数据模型(业务表)上有哪些是可以共用的?
-
也有一些不同点,数据模型(业务表)上哪些最好是隔离的?
-
代码层面是否可以使用设计模式抽象一些公有逻辑,减少代码复杂度?
-
合并后,如果海外仓还想继续用单一模式,怎么办?
三、如何取舍数据模型的共用与隔离?
两套系统主要还是调度实体不同,我们采用了分层设计原则:上层共用、下层隔离。
在上层的单据层、库存商品层,比如出库单、出库单明细、出库作业单、二级库存,其实都是一致的,两套系统可以共用。
下层的调度任务两者不同,所以我们上层的数据模型不变,下层的调度任务,比如出库任务、理货任务、盘点任务、上架任务都做了分离。
分层图如下:

四、设计模式与代码复用优化
4.1 抽出任务基类
单据调度任务一般包括:
-
唯一任务 ID
-
状态
-
小车编码
-
小车类型
-
优先级
-
库区
-
状态是否变化
-
……
这些都是料箱业务和货架业务公有的内容,这样定义子类时字段会少许多,保持代码整洁性。
我一直秉承的一个观点是系统的可维护性来源于细节,看似只是抽出了几个基类,但只要处处做到这种复用性,系统会变得清晰许多。
4.2 实操推送使用工厂方法、模板方法、策略模式
我们的实操任务类型有许多种,包括:
-
料箱到人在线出库
-
货架到人在线出库
-
料箱到人在线直接上架
-
料箱到人在线空箱上架
-
料箱到人在线空箱出库
-
料箱导入在线推荐上架
-
……
这么多的实操任务,如果写 if else 会很长,那么我们可以用经典的工厂方法 + 模板方法 + 策略模式,来组合实现这个功能。
大致类图:

五、如何保证业务兼容性?
第 3 个要考虑的点是,我们合并之后,万一仓库只想使用单一业务场景,融合后可以支持吗?
当然是可以的。
5.1 调度层面
单据调度任务是有库区属性的,单个任务只可能命中单库区,所以在计算任务的时候把库区加上就行了。
5.2 实操页面
station 工作流也支持,因为本来就是按调度任务的到站推送来展示的,只要下层的调度任务能区分,工作流实操也能区分。
5.3 业务模式
上面两点式库区模式不同,如果是同一个库区,但库区业务模式不同,又该如何支持?
我们可以做配置化,工作站按需配置业务模式。
5.4 定时任务的精细化管理
上述第3点 指的是业务模式的入口支持配置化,但对于下层的任务调度定时器,如果现场不启用某些业务模式,是否可以直接关闭对应的定时任务?
答案自然也是可以的,但本期重构没做,后期我们接入了 XXL-JOB,支持定时任务的管理。