WES 系统重构前,总代码行数接近八十多万,在这八十多万行代码中,既存在非常多的重复逻辑,又存在非常多的变化逻辑,前者可以通过不断地抽取公共逻辑来达到去重、瘦身的效果。

后者的治理则更为复杂一些,需要做很多抽象与统一整合,也就是策略规则。

坦诚来说,重构之前对规则引擎一点都不了解,自己也是在不断地接触和学习,扩宽自己的技术栈广度。回过头来,发现做重构确实让自己成长得很快。

一、正视复杂性:WES 业务规则的“多”与“变”


在深入技术选型之前,我们首先要清晰地定义问题。WES 作为仓储执行的入口,其核心复杂度在于其需要应对B 端多变且相互交织的业务规则。这些规则直接体现了不同客户、不同业务场景下的运营策略。

  • 规则的维度多:仅出库环节,就涉及单据创建与提交策略(如自动拆合单、静态组波)、出库优先级调整策略(按发货时间、作业时长、剩余任务数动态调整)、库存分配策略(多库区优先级)、工作站作业策略(绑箱、槽位匹配与释放)等数十个可配置项。

  • 规则的逻辑条件复杂:一个策略的生效往往是多重条件组合判断的结果。例如,“出库单初始优先级”策略,需要根据“出库单类型”来决定其初始的“优先级等级”和“优先级值”。这种 if...else if...else的链式判断,在传统编码中会形成难以维护的“代码沼泽”。

  • 规则的动态性要求高:业务策略并非一成不变。新的客户需求、运营优化尝试都要求规则能够快速调整、热生效,而不需要重启服务或发布新版本。例如,快速调整“缺货提交方式”为“有货先作业”以应对临时的爆仓压力,必须是分钟级可配置的能力。

面对这种“多、变、杂”的业务规则,如果继续沿用硬编码的方式,会直接导致:

  1. 核心业务逻辑与规则逻辑耦合:业务代码中充斥着规则判断,可读性急剧下降。

  2. 维护成本高昂:任何微小的规则变更都需要开发人员介入修改代码、测试、上线,无法快速响应业务。

  3. 知识壁垒:业务规则散落在数十万行代码中,新人难以理解,业务专家(如资深的仓储规划师)也无法直接参与规则的制定与调整。

二、技术选型思考:为什么是 Drools?

基于上述痛点,我们明确了引入规则引擎的核心目标:将易变的业务规则从稳定的程序逻辑中解耦出来,实现业务规则的统一管理、可视化和动态配置。

在选型时,我们考察了多种方案:

  1. 脚本引擎(如 Groovy, Lua):灵活性高,但对于复杂的条件网络和规则推理支持较弱,需要自行实现优先级、冲突解决等机制,开发量和复杂度不可控。

  2. 自定义规则解析器(如 XML/JSON 配置 + 自研引擎):初期看似简单,但随着规则复杂度的提升,自定义的语法和引擎在性能、功能完备性上很难与成熟产品媲美,容易重复造轮子且后期难以维护。

  3. 商用规则引擎:功能强大,但存在商业许可成本,与我们的开源技术栈整合和自主可控的要求不符。

最终,我们选择了 Drools,主要基于以下几点考量:

  • 成熟性与社区生态:Drools 是 JBoss 旗下的开源项目,经过多年发展,社区活跃,文档丰富,是一个非常成熟、稳定的企业级规则引擎解决方案。

  • 强大的规则表达能力:其核心的 DRL(Drools Rule Language)语言专为规则设计,支持声明式的规则编写(When-Then),天然契合我们的业务场景。它内置的 RETE 算法对于处理大量规则和数据有很高的效率。

  • 与 Java 技术栈的无缝集成:WES 核心系统基于 Java 技术栈,Drools 可以非常方便地集成到 Spring 等主流框架中,降低了引入新技术栈的架构风险和学习成本。

  • “可进化”的架构潜力:Drools 不仅是一个规则执行引擎,其提供的 **KIE(Knowledge Is Everything)**​ 工作台概念,为我们未来构建图形化、Web 化的策略规则管理平台(正如策略中心)奠定了坚实的技术基础。

三、架构与落地:将业务规则抽象为 Drools 规则

选型只是第一步,如何将复杂的业务规则优雅地映射到 Drools 的规则模型中,是体现架构能力的关键。

1. 核心模型抽象

我们首先对策略中心的配置进行了领域模型抽象。每一个策略项(如“出库单初始优先级”)被抽象为一个 Policy聚合根,其下包含多条有序的 Rule。每条 Rule由 Condition(匹配条件)和 Action(结论数据)组成。这个领域模型与 Drools 的 RuleLHS(Left Hand Side), RHS(Right Hand Side) 概念可以完美对应。

2. 动态规则加载

我们并没有让业务人员直接编写 DRL 文件,而是基于策略中心的数据库配置,在运行时动态生成 DRL 规则内容。系统启动或策略变更时,会从数据库拉取最新配置,通过模板技术将其转换为标准的 DRL 语法,然后加载到 Drools 的 KieSession中。这样,策略中心UI上的每一次“保存”操作,就相当于完成了一次业务规则的“发布”。

3. 规则执行与集成

在业务逻辑的关键节点(如“创建出库单”、“分配库存”前),我们将业务对象(如 Order对象)作为 Fact插入到 KieSession中,触发规则引擎执行。引擎会根据定义的规则顺序和优先级,对 Fact进行匹配和推理,并执行相应的 Action,修改对象的状态。执行完毕后,我们只需取出被规则修改过的对象,继续后续的业务流程即可。整个过程对核心业务代码几乎是透明的。

四、重构收益

引入 Drools 规则引擎后,我们获得了显著的收益:

  • 架构清晰,职责分离:业务代码不再关心“如何判断”,只关注“做什么”,代码变得简洁、可读、易测试。

  • 响应速度飞跃:常用规则基本百分百覆盖,现在可以由实施顾问或运维人员通过策略中心界面直接完成,无需开发介入,开新仓的时候,直接可以按需配置。