规则引擎

【一、什么是规则引擎

    规则引擎这个词在百度上有非常宏大的定义,即“实现了将业务决策从应用程序代码中分离出来,它接受数据输入,解释业务规则,并根据业务规则做出业务决策”,好生抽象啊,好在我所期望的规则引擎无需那么的高大上。最近在思考如何抽象一个简易的工作流引擎,在单条串联式的流程中毫无压力,比如“小李申请请假–>项目经理审核”大概就结了,而在类似“分支”判断的情形时,竟如鲠在喉,有一个问题无法释怀“如何在工作流运行时动态地根据用户的输入值来判定流程的流转方向?”,比如“小张请假天数为两天之内就按正常流程走,而如果请假天数在三天或三天以上,则需要进一步提交到总经理进行审核”,大家有碰到过这个问题吗?显然,流程的流转是由小李所填写请假单的天数来决定的。如果我的应用程序是“写死的”,写个“if-else”也就解决问题了,但是现在问题已升华到“引擎”了,不可能去写基于 C#或Java 的判断语句了,一开始在思考这个问题时,我幻想“把 if-else 语句想办法存在配置文件或SQL数据库里,当程序运行时再拿出来运行”,行文至此,仍不免一笑,C#或Java 作为编译型语言怎么可能“拎起来”就执行,以现在的眼光看问题是可笑的,但思路却由此打开。
 
【二、我所理解的规则引擎是什么】
    了解到行业性的规则引擎概念以及我自己的切身使用场景后,我最想要的规则引擎也就清晰了。在摸索的过程中,先后学习了 Drools.NET(官网,教程) 和 NxBRE(教程),这两个开源规则引擎很完善、很宠大,它们能解决我的问题但显臃肿,我需要的是轻量级,我只不过是“想在运行时执行一个业务逻辑判断,然后返回一个值”就可以了,期间我考虑使用 IronPython,转悠一圈发现开发成本相当大,继续寻找,于是“A2D-Framework REngine(Github)”走进了我的视线。
 
【三、它在工作流引擎中是起什么作用的?】
    REngine 很轻便的解决了我一直头疼的问题,它是在(.NET C#)运行时通过执行 JavaScript 引擎来获取一个结果,进而反馈给 C#。
    哎呀,当问题得到了合理的归类分化,世界一下子透明了许多!
    方案在手,紧接着我规划如下:C#只需要关心流程的流转,再配以持久层存储到数据库即可,至于工作流该如何流转、流转的条件是什么(比如:请两天假就按正常流程走,请三天假则另需总经理首肯),这些问题统统交由规则引擎 REngine 来处理就好,REngine 的核心是一个 JavaScript 引擎,它可以接受一切的“合乎 JavaScript 语言规范”的文本,通过 JavaScript 的即时解释特性以达到运算的目的,这提到的“文本”就是 REngine 引擎所需的规则文件,它以“.rule”为后缀名,怎么理解这个规则引擎的工作机制呢?它与控制反转 Ioc 可作同一类比:REngine 引擎与其规则文件,就如同 Ioc 与其 XML 配置文件是一样一样儿的,当规则有变时,就像 Ioc 中接口的实现有变更,只需改一下新的对应实现类就可以。
    显然,规则的变更,瞬间就提升到了配置化的层面,为工作流引擎、为项目的高维护性注入了信心。
 
【四、简介 Aaron 的规则引擎】
规则引擎 REngine 系 Aaron 的作品(去博客园了解他)。
REngine 的规则文件(.rule)形如:
规则引擎-风君雪科技博客

1
2
3
4
5
6
7
8
9
10
11
12
13

#region 请假规则
    rule default
        return "";
    end rule
 
    rule AskForLeaveFork
        if(Leave <= 2)
            return "toLeader";
        else if(Leave > 2)
            return "toGeneralManager";
    end rule
 
#endregion

如果这个工作流引擎移到另一个项目,根据他们的需求,发现请假天数的界限是 3 天,那直接把规则中的 2 改为 3 即可,如果判断规则有大的变化,那重新写 if-else 判断即可,只需要遵循 JavaScript 语言规范即可

 
【五、总结规则引擎的好处】
    为工作流引擎在类似“分支”判断这样的场景编写业务规则,引导流程作出正确的流转;当规则有变更时,只需修改规则,或者在UI界面上修改也行,即存即用,这样 .NET 程序无需再编译、再部署。
 
此文仅作抛砖引玉,期待热衷工作流和规则引擎的朋友们留言斧正,感激不尽!