暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

写出个灵活的系统竟然可以如此简单!小白也能写出高级的Java业务!

源话编程 2024-08-07
104

👋 热爱编程的小伙伴们,欢迎来到我的编程技术分享公众号!在这里,我会分享编程技巧、实战经验、技术干货,还有各种有趣的编程话题!

在软件开发中,面对复杂多变的业务需求,代码的可维护性和可扩展性成为了不可忽视的问题。尤其是在处理类似短信业务这样的场景,当涉及到多个第三方供应商的选择、动态判断以及频繁的变更时,传统的硬编码方式往往显得力不从心。本文将分享一个使用 LiteFlow 规则引擎优化短信业务系统的实践过程,展示如何通过规则引擎来简化逻辑、提高代码的灵活性和可维护性。

一、背景与挑战

在公司短信业务系统中,存在多个第三方短信供应商,每个供应商提供的短信包数量、价格、发送速度等各不相同。系统需要根据业务需求和供应商状态动态选择最合适的供应商进行短信发送。然而,现有的代码逻辑复杂且混乱,通过串行查询和大量的 if-else 嵌套来实现供应商的选择和短信的发送,不仅效率低下,而且难以维护和扩展。

二、LiteFlow 规则引擎的引入

在小组交流会上,我了解到 LiteFlow 这一国产规则引擎,它支持复杂的流程编排、热刷新以及灵活的规则定义。通过 LiteFlow,我可以将复杂的业务逻辑抽象成简单的规则表达式,实现代码的解耦和灵活配置。

LiteFlow 的规则定义简洁明了,使用 EL 表达式来编写流程规则,大大降低了学习成本。例如,使用 LiteFlow 可以轻松表示出复杂的流程关系,如串行执行、并行执行以及基于条件的分支选择等。

上图在 LiteFlow 用规则表示就是:

<chain name="chain1">
    THEN(
        a,
        WHEN(b, THEN(c, d)),
        e
    )
</chain>

其中THEN
是代表串行,WHEN
代表并行执行。

在LiteFlow里规则表示就是:

<chain name="chain1">
    THEN(
        a,
        WHEN(
            b,
            SWITCH(c).to(d,e)
        ),
        f
    )
</chain>

其中SWITCH
关键字就是排他网关的意思,c 这个组件是一个 java 类,根据执行的结果去选择到底应该执行 d 还是 e。

LiteFlow 的文档里作者给出了很详细的例子,还有一些复杂例子,比如:

这种复杂的例子用LiteFlow的表达式可以写成:

<chain name="chain1">
    THEN(
        A,
        WHEN(
            THEN(B, C),
            THEN(D, E, F),
            THEN(
                SWITCH(G).to(
                    THEN(H, I, WHEN(J, K)).id("t1"),
                    THEN(L, M).id("t2")
                ),
                N
            )
        ),
        Z
    )
</chain>

它的表达式还可以进行定义子变量,上述表达式又可以写成:

<chain name="chain1">
    item1 = THEN(B, C);
    item2 = THEN(D, E, F);
    item3_1 = THEN(H, I, WHEN(J, K)).id("t1");
    item3_2 = THEN(L, M).id("t2");
    item3 = THEN(SWITCH(G).to(item3_1, item3_2), N);
    
    THEN(
        A,
        WHEN(item1, item2, item3),
        Z
    );
</chain>

三、短信业务系统的重构

在深入了解 LiteFlow 后,我开始对短信业务系统进行重构。首先,我将原有的大段业务逻辑拆分成多个独立的组件,每个组件负责单一的职责,如查询供应商短信包数量、选择最佳供应商、发送短信等。然后,使用 LiteFlow 的规则表达式来编排这些组件的执行顺序和条件。

以下是重构后的短信业务流程规则示例:

<flow>
    <chain name="channelSenderChain">
        <!-- 选择最佳渠道 -->
        <selectBestChannel>
            THEN(
                WHEN(
                    channel1Query, channel2Query, channel3Query,
                    channel4Query, channel5Query, channel6Query
                ),
                channelSelector
            ).id("selectBestChannel");

        <!-- 根据业务选择渠道 -->
        <selectBizChannel>
            THEN(
                biz1,
                SWITCH(if_2).to(
                    channel3,
                    channel4,
                    SWITCH(if_3).to(channel5, channel6).id("s3")
                ).id("s2")
            ).id("selectBizChannel");

        <!-- 主流程 -->
        THEN(
            packageData,
            SWITCH(if_1).to(
                channel1,
                channel2,
                selectBestChannel,
                selectBizChannel
            ),
            batchSender
        );
    </chain>
</flow>

通过这种方式,我成功地将复杂的业务逻辑抽象成了清晰的规则表达式,每个组件之间通过上下文进行数据传输,实现了高度的解耦。当业务需求发生变化时,我只需修改规则文件而无需改动代码,大大提高了系统的可维护性和可扩展性。

四、LiteFlow 的额外优势

在重构过程中,我还发现了 LiteFlow 的一些额外优势:

  • 热刷新:LiteFlow 支持规则文件的热刷新,无需重启应用即可更新流程规则。这一特性在开发过程中非常有用,可以大大提高开发效率。
  • 脚本组件:LiteFlow 支持 Groovy 等脚本语言编写的组件,这意味着可以在不重启应用的情况下更新业务逻辑,进一步提高了系统的灵活性。
  • 多线程支持:虽然 LiteFlow 主要用于规则编排,但其提供的链式组装规则也可以用于简单的多线程编程,降低了多线程编程的门槛。

示例:https://github.com/bryan31/message-demo/tree/master

结语

通过引入 LiteFlow 规则引擎,我成功地对短信业务系统进行了重构和优化。新的系统架构更加清晰、灵活且易于维护。未来,我还计划进一步探索 LiteFlow 的高级特性,如隐式流程、事件回调、组件切面等,以更好地满足复杂业务场景的需求。

同时,我也将这一实践经验分享给了团队成员,希望能够推动整个团队的技术进步和代码质量的提升。我相信,在 LiteFlow 的帮助下,我们将能够构建出更加高效、可靠和可扩展的软件系统。

来源:https://segmentfault.com/a/1190000042084710


文章转载自源话编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论