2008-10-30 146 views
61

我正在审计一个项目,该项目使用所谓的Rules Engine。简而言之,它是从应用程序代码中外化业务逻辑的一种方法。规则引擎 - 优缺点

这个概念对我来说是全新的,我很怀疑它。在过去几年中听到人们谈论Anemic Domain Models之后,我在质疑规则引擎方法。对我来说,他们似乎是减弱域模型的好方法。例如,我正在做一个java webapp与一个规则引擎交互。然后我决定我想要一个基于相同域的Android应用程序。除非我想让Android应用程序与规则引擎进行交互,否则我将不得不错过已写入的任何业务逻辑。

由于我还没有任何经验,只是好奇心,我有兴趣听说利弊是在使用规则引擎?我能想到的唯一一个专业人员是,您不需要重新构建整个应用程序来改变一些业务规则(但真的,有多少应用程序真的有这么多的改变?)。但是使用规则引擎来解决这个问题对我来说就像是在霰弹枪伤口上施加一个创可贴。

更新 - 自写这篇文章以来,神本人Martin Fowler拥有blogged about using a Rules engine

+0

您是否正在寻找任何第三方产品,或者您打算推出自己的产品? – 2008-10-31 16:59:01

+3

这是Martin Fowler的一篇很棒的文章,谢谢! – 2009-09-16 21:07:00

+0

你是对的 - 他们非常反OO。他们来自OO不常见的情况(这部分解释了它),但是他们非常希望与您说的“贫血”的记录/价值对象一起工作。这不一定是坏事,但它就是这样。如果你不喜欢这样 - 你不会喜欢规则引擎。 – 2010-11-08 00:42:54

回答

36

我见过的大多数规则引擎被系统代码视为黑盒子。如果我要建立一个领域模型,我可能希望某些商业规则是领域模型的内在特征,例如告诉我对象何时具有无效值的业务规则。这允许多个系统共享域模型而不需要复制业务逻辑。我可以让每个系统使用相同的规则服务来验证我的域模型,但这似乎削弱了我的域模型(正如问题中指出的那样)。为什么?因为我始终依靠系统程序员来决定何时应该执行业务规则(通过调用规则服务),而不是始终在所有系统上始终执行业务规则。如果域模型对您来说完全填充,这可能不会成为问题,但如果您要处理在其生命周期中更改域模型中的值的用户界面或系统,则可能会出现问题。

还有另一类业务规则:决策制定。例如,一家保险公司可能需要对承保申请人的风险进行分类并收取保费。您可以将这些类型的业务规则放置在您的域模型中,但对于这种场景的集中决策通常是可取的,实际上,它们非常适合面向服务的体系结构。这确实讨论了为什么使用规则引擎而不是系统代码。规则引擎可能是更好的选择的地方是负责决策的业务规则随着时间的推移而变化(正如其他一些答案指出的那样)。

规则引擎通常允许您在不重新启动系统或部署新的可执行代码的情况下更改规则(无论您从供应商那里得到什么承诺,确保您在非生产环境中测试您的更改,因为即使规则引擎完美无瑕,人类仍在改变规则)。如果你想,“我可以通过使用数据库来存储改变的值”,你是对的。规则引擎不是一个能够做出新事物的神奇盒子。它旨在成为提供更高抽象级别的工具,因此您可以更少关注重新发明轮子。许多供应商通过让您创建模板来进一步实现这一目标,以便业务用户可以填充空白而不是学习规则语言。

关于模板的一个小心谨慎:与编写没有模板的规则相比,模板永远不会花费更少的时间,因为模板必须至少描述规则。计划一个更高的初始成本(就像建立一个使用数据库来存储更改值的系统,而不是直接在系统代码中编写规则一样) - ROI是因为您节省了将来维护的系统代码。

18

我见过的规则引擎最大的特点就是它可以让业务规则所有者实现业务规则,而不是把责任推给程序员。即使你有一个敏捷的流程,你不断地从利益相关者那里得到反馈,并且经历了快速的迭代,但它仍然不能达到让制定业务规则的人也能实现的效率水平。

另外,如果规则嵌入代码中,则不能过分强调删除可能由简单规则更改导致的重新编译重新测试重新部署周期的价值。经常有几个团队参与到构建的祝福中,并且使用规则引擎可以使许多不必要的事情发生。

23

规则引擎在某些情况下可以提供很多价值。

首先,许多规则引擎以更具说明性的方式工作。一个非常粗略的例子是AWK,您可以在其中分配正则表达式到代码块。当文件扫描器看到正则表达式时,将执行代码块。

你可以看到,在这种情况下,如果你有一个大的AWK文件,并且你想添加另一个“规则”,你可以很容易地到文件底部,添加你的正则表达式和逻辑,并完成它。具体而言,对于许多应用程序,您并不特别关心其他规则在做什么,并且规则并不真正互相操作。

因此,AWK文件变得更像是一个“规则汤”。这种“规则汤”的性质让人们非常紧张地关注他们的领域,而很少关注系统中可能存在的所有其他规则。

例如,弗兰克对总价值超过1000美元的订单感兴趣,因此他提出了他感兴趣的规则系统。 “如果order.total> 1000那么电子邮件弗兰克”。同时,Sally希望来自西海岸的所有订单:“IF order.source =='WEST_COAST'THEN给Sally发邮件”。

所以,你可以看到在这个微不足道的,人为的情况下,一个订单可以同时满足两个规则,但是两个规则都是相互独立的。来自西海岸的1200美元订单通知Frank和Sally。当弗兰克不再担心的时候,他只是简单地从汤里抽出他的排除。

对于很多情况下,这种灵活性可能非常强大。它也可以像这种情况一样向最终用户公开最简单的规则。使用高级表达式和可能轻量级的脚本。

现在,显然,在一个复杂的系统中可能会发生各种相互关系,这就是为什么整个系统不是“完成规则”的原因。有人在某个地方负责规定不会失控。但这并不一定会降低系统所能提供的价值。

注意,这甚至不涉及专家系统,其中规则触发了规则可以创建的数据,而是更简单的规则系统。

无论如何,我希望这个例子展示了一个规则系统如何帮助扩大一个更大的应用程序。

8

它(如其他所有)取决于您的应用程序。对于某些应用程序(通常是那些永远不会改变的规则或规则对现实生活常数最好的应用程序,即不会在非常规条件下发生明显变化,例如物理属性和公式),使用规则引擎是没有意义的,它只是引入了额外的复杂性,并要求开发人员拥有更大的技能。

对于其他应用程序,这真是个好主意。以订单处理为例(订单是从发票到处理货币交易的任何事情),每隔一段时间,对某些相关法律或法规(司法意义上)要稍作修改,要求您履行新的要求(例如销售税,经典)。 而不是试图强制你的旧应用程序进入这种新的情况,突然之间你必须考虑销售税,而在以前没有的情况下,更容易适应你的规则集,而不是必须在潜在的大量的代码。

然后,您当地政府的下一个修订要求在一定标准内报告所有销售情况,而不是必须进入并补充说明。最后,你会得到非常复杂的代码,当你转身想要恢复其中一个规则的效果,而不会影响所有其他规则时,这将很难管理。

5

到目前为止,每个人都有对规则引擎非常乐观,但我建议读者谨慎。当问题变得更加复杂时,您可能会突然发现整个规则引擎已经变得不合适,或者比使用更强大的语言更复杂。此外,对于许多问题,规则引擎将无法轻松检测到可大大减少评估条件的运行时间和内存占用量的属性。我相对较少的情况是我更喜欢规则引擎到依赖注入框架或更动态的编程语言。

3

“但是真的,有多少应用程序真的有这么多的变化?”

老实说,我所从事的每一个应用程序都经历了严肃的工作流程和/或从概念到逻辑的变化,直到部署完成。这是“维护”编程的首要原因......

现实情况是,您无法事先考虑所有事情,因此也就无法考虑敏捷流程的原因。此外,广管局似乎总是错过重要的东西,直到在测试中发现它为止。

规则引擎强制您真正将演示和存储的业务逻辑分开。此外,如果使用正确的引擎,您的BA可以根据需要添加和删除逻辑。正如Chris Marasti-Georg所说,它将责任推到广管局。但更重要的是,它可以让广管局得到他们要求的确切内容。

12

我写了一个客户端的规则引擎。最大的胜利是包括所有的利益相关者。引擎可以运行(或重放)查询并解释文本中发生了什么。业务人员可以查看文本说明,并快速指出规则,例外和其他特殊情况中的细微差别。一旦涉及商业方面,验证就会变得更好,因为它很容易得到他们的意见。此外,规则引擎可以独立于应用程序代码库的其他部分,因此您可以跨应用程序使用它。

这个骗局是有些程序员不喜欢学得太多。规则引擎和你投入它们的规则,以及实现它们的东西,可能有点多毛。尽管一个好的系统可以很容易地处理病态和扭曲的逻辑网络(或者经常不合逻辑),但并不像编写一堆陈述(不管一些头脑简单的规则引擎所做的那样)简单。规则引擎为您提供处理规则关系的工具,但您仍然必须能够想象出所有这些。有时候就像生活在电影巴西。 :)

2

规则引擎是可配置应用程序上的一个胜利,如果可以避免的话,您不希望自定义构建。他们也善于集中规则和算法的大型基础,如Rete对于快速匹配大型规则集非常有效。

24

我认为你对贫血域模型的担忧是有效的。

我见过在生产著名的商业规则Rete算法发动机运行的两个应用程序,我的工作。我会考虑一个成功,另一个失败。

的成功应用是决策树的应用程序,包括的约30个各分〜10棵树。规则引擎有一个用户界面,可以让业务人员维护规则。

不太成功的应用程序有〜3000条规则冲击规则数据库。当添加新规则时,没有人知道是否存在冲突规则。对Rete算法有一点了解,并且产品的专业知识已经离开了公司,所以它变成了一个不可触及和不可修复的黑盒子。部署周期仍受规则更改的影响 - 必须在更改规则时完成完整的回归测试。记忆也是一个问题。

我会轻轻一点。当规则集规模适中时,很容易理解变化,就像上面给出的简单电子邮件示例一样。一旦规则数量攀升到数百个,我认为你可能会遇到问题。

我还担心一个规则引擎成为应用程序中的单瓶颈。

我没有看到使用对象作为划分规则引擎空间的方式。在遵循私有规则引擎的对象中嵌入行为对我来说似乎没有问题。当规则引擎要求状态不是其对象的一部分才能正常触发时,问题会触及你。但这只是设计难度的另一个例子。

2

很多好的答案已,但想补充一两件事情:

  1. 在自动化任何一个复杂的决定关键事迅速成为你的管理,而不是执行所涉及的逻辑能力。规则引擎无助于此 - 您需要考虑业务规则管理系统具有的规则管理功能。大多数商业和开放源代码规则引擎已经发展成为带有存储库的规则管理系统,报告规则使用情况,版本控制等。构建成协调一致的规则集以进行业务决策的规则存储库比任一规则更容易管理数千行代码或规则汤。
  2. 有很多方法可以使用基于规则的声明式方法。使用规则来管理UI或作为定义流程的一部分可能非常有效。然而,规则方法的最有价值的用途是自动化业务决策,并将其作为松散耦合的决策服务来实现,这些决策服务采取输入,执行规则并返回答案 - 一个决定。这些服务可以回答其他服务的问题,例如“这个客户是一个很好的信用风险”,或者“我应该给这个客户这个订单什么样的折扣”或者“这个客户此时最好的交叉销售是什么。这些决策服务可以使用规则管理系统非常有效地构建,并允许随着时间的推移轻松整合分析,这是许多决策受益的原因。
1

我见规则,流程和数据引擎(又名数据库)作为基本是相似的。但是,由于某种原因,我们从不说黑盒子持久化子系统是不好的。

其次,从我的POV,贫血模型是不是一个在执行行为的光,它是一个很轻的行为本身。描述域模型对象中可用行为的实际方法不必由对象本身完成。

0

从我的规则引擎体验最大的复杂性在于:

  1. 从OOP POV这是一个真正的痛苦重构并写入,而你正在重构代码说明性语言,影响他们的测试规则。
  2. 通常我们应该总是考虑规则的执行顺序,当有很多规则时它们会变成一团糟。
  3. 一些细微的变化可能会导致导致生产错误的规则行为不正确。在实践中,预先覆盖所有的案例并不总是可能的。
  4. 规则使其他规则中使用的对象变异也会增加复杂性,从而导致开发人员将其分解为多个阶段。