肥仔教程网

SEO 优化与 Web 开发技术学习分享平台

再见了 if-else,liteflow 真的太香了!

说实话,if-else 写多了,真的有点上头。

尤其是在那种复杂业务流程一层套一层的项目里,页面流程一变,业务需求一加,代码就开始“如山倒”地冗长,真是改一行代码就像踩地雷,一不小心整个功能都塌了。你可能也遇到过这种情况:一个流程涉及十几个环节,每个环节都有一堆判断逻辑,流程改一下,十几个判断都要重新评估。

所以当我第一次看到 liteflow 这个规则引擎的时候,老实讲,我是带着一点点怀疑的。轻量级?高性能?还热部署?听起来有点像是“我全都要”的理想型框架。结果用了之后,竟然还真香了……

以前的 if-else,像是用胶水贴流程

我们先回忆一下常规写法,假设是一个订单支付完成后的流程,逻辑大概是这样的:

if (订单完成) {
    发放积分();
    发送MQ();
    if (需要发短信) {
        发送短信();
    }
    if (需要发邮件) {
        发送邮件();
    }
}

上面这只是最简单的示意,真正在业务里你会发现:每个逻辑块本身又是一堆判断,还要处理异常、中断、重试等等,维护成本直线上升。而且这东西最要命的是——流程的顺序、结构都写死了,任何变动,都得改代码。

用 liteflow 搞定流程,像是拼乐高

liteflow 是一个规则编排引擎,说人话就是:它允许你用配置规则的方式把流程节点像乐高一样拼接起来,再也不用死磕 if-else 了。

你可以把每个业务处理块抽象成一个“组件”,然后用 XML(也支持 JSON/YAML)来编排这些组件的执行顺序。

比如订单完成后的流程,在 liteflow 中的定义就是:

<chain name="order_finish_flow">
    THEN(prepareTrade, grantScore, sendMq, WHEN(sendEmail, sendPhone))
</chain>

这串规则什么意思?串行执行:先准备交易、发积分、发消息,然后并行地发短信和发邮件。流程读起来清晰得跟念口诀一样,连新来的实习生看了都能大概懂什么意思。

而且你要是突然想加个“推送APP消息”的逻辑?只要把 sendAppNotify 加进 XML 就行,代码都不用动。

一个 Node,统一管理,统一调度

所有的业务逻辑,最终都会落到一个个 node(节点)上执行,而每个 node 就是一个 Java 类,继承自 NodeComponent

比如这个是发积分的 node:

@Component("grantScore")
public class GrantScoreNode extends NodeComponent {
    @Override
    public void process() {
        OrderContext ctx = this.getContextBean(OrderContext.class);
        // 获取用户、订单信息,计算积分
        int points = calcScore(ctx.getOrderAmount());
        userService.addScore(ctx.getUserId(), points);
    }
}

你是不是发现了?this.getContextBean(OrderContext.class) 就是流程的上下文,我们可以直接在 node 里取值、传值,不需要方法参数传来传去了。上下文对象可以定制,比如你可以创建 OrderContext 来包含当前订单的所有状态。

而且每个 node 还可以做这些事:

  • isAccess():判断这个节点是否需要执行,像是“条件执行”
  • isContinueOnError():出错了要不要继续往下跑
  • isEnd():是否终止流程

非常灵活,非常轻巧。

条件判断?用 IF 和 SWITCH 优雅解决

liteflow 提供了两个特殊组件:

  • NodeIfComponent
  • NodeSwitchComponent

它们分别用来处理 if 和 switch 的业务场景。举个例子:

@Component("isVipUser")
public class IsVipUserIfNode extends NodeIfComponent {
    @Override
    public boolean processIf() throws Exception {
        OrderContext ctx = this.getContextBean(OrderContext.class);
        return ctx.isVip();
    }
}

然后你可以在规则文件中这么写:

THEN(IF(isVipUser, grantVipScore), normalScore);

是不是一下子比嵌套 if-else 清晰多了?流程逻辑直接写在 XML 中,能不能进 grantVipScore 是根据 isVipUser 组件的判断结果来的。再复杂点的也不怕,直接 switch 上:

SWITCH(userType).to(processVip, processNormal, processBlackList);

灵活得像前端的路由系统。

并行处理真的爽,when 关键字安排上

在传统代码里,想要做并行处理得怎么整?线程池、异步回调、结果合并、异常处理,一套流程下来堪称“费脑风暴”。

liteflow 提供了一个关键词:WHEN,一切并行,都靠它。像下面这个配置:

THEN(a, WHEN(b, c, d), e)

表示:先执行 a,然后并行跑 b/c/d,等并行完成后再跑 e。自动并行、自动等待、自动异常捕获,线程池也帮你配好了,不香吗?

默认配置下它使用一个全局异步线程池,你也可以通过配置文件来自定义最大线程数、等待时间、队列大小:

liteflow:
  when-max-wait-seconds: 10
  when-max-workers: 32
  when-queue-limit: 1000

反正你只管写业务逻辑,执行层面的事交给它。

业务规则能热部署,开发调试更丝滑

传统代码改逻辑要干嘛?改代码、重启服务、联调……一通操作下来搞半天。

liteflow 支持热部署,只要你用外部存储的规则文件(比如 Nacos、Apollo、ZooKeeper 等),改完之后立马生效,服务根本不用重启。

流程逻辑变动变得很轻松,像改个前端页面似的。

开发调试时,它还能打印每个节点的执行耗时,失败日志都有,非常方便排查问题。

实战落地:订单完成后的并行通知流程

我在项目里就实打实用了 liteflow 来处理订单完成后的异步任务,像是发积分、消息推送、短信通知、邮件提醒,这些流程本来是用异步事件处理的,整合到 liteflow 之后,结构清晰,新增流程也方便。

<chain name="order_finish_flow">
    THEN(initOrder, grantScore, sendMq, WHEN(sendEmail, sendSms))
</chain>

每个 node 的代码都很简单,处理逻辑单一,测试覆盖也容易做,不会互相耦合。最重要的是,测试同事看着规则文件都能理解流程,沟通效率大幅提升。

而且我们还用 isAccess() 控制流程,比如遇到非会员就跳过发积分逻辑,避免执行无意义代码,系统资源更节省。

最后

当然了,liteflow 虽然轻量,但也不是万能的。

如果你业务流程真的是“错综复杂、状态回溯、人工介入、审批回退”,那你还是该上 BPM 工作流系统(比如 Activiti、Flowable、Camunda)。liteflow 更适合逻辑结构稳定、但执行内容经常变动的场景,比如电商订单处理、内容审核流、营销活动流程等等。

如果你现在正被各种 if-else 套娃搞到心态爆炸,不妨试试把流程组件化交给 liteflow 来调度。

你会发现,原来把流程写清楚,还真能让人心情舒畅。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言