规则引擎 - 优点和缺点

时间:2008-10-30 14:42:52

标签: rule-engine

我正在审核一个使用所谓Rules Engine的项目。简而言之,它是一种从应用程序代码中外部化业务逻辑的方法。

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

由于我对它们没有任何经验,只是好奇,我有兴趣了解使用规则引擎的优点和缺点?我能想到的唯一一个专业是你不需要重建你的整个应用程序只是为了改变一些业务规则(但实际上,有多少应用确实有那么多变化?)。但是使用规则引擎来解决这个问题对我来说就像在霰弹枪伤口上放一个创可贴一样。

更新 - 自写这篇文章以来,上帝本人Martin Fowler已blogged about using a Rules engine

12 个答案:

答案 0 :(得分:36)

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

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

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

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

答案 1 :(得分:25)

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

我见过两个应用程序,一个着名的商业Rete规则引擎在我工作的生产中运行。我认为一个是成功而另一个是失败。

成功的应用程序是一个决策树应用程序,由~10棵树组成,每棵树约有30个分支点。规则引擎有一个UI,允许业务人员维护规则。

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

我会轻描淡写地说。当规则集的大小适中时,很容易理解更改,例如上面给出的简单电子邮件示例。一旦规则数量攀升到数百个,我认为你可能会遇到问题。

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

我认为使用对象作为分区规则引擎空间的方法并没有错。在遵循私有规则引擎的对象中嵌入行为对我来说似乎没问题。当规则引擎需要不正确触发其对象一部分的状态时,问题就会出现。但这只是设计难度的另一个例子。

答案 2 :(得分:24)

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

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

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

因此AWK文件变得更像“规则汤”。这种“规则汤”性质让人们可以非常关注他们的域名,而不必担心系统中可能存在的所有其他规则。

例如,弗兰克对总额超过1000美元的订单感兴趣,因此他投入了他感兴趣的规则系统。 “如果order.total> 1000那么电子邮件Frank”。

与此同时,莎莉想要来自西海岸的所有订单:“IF order.source =='WEST_COAST'然后发送电子邮件给莎莉。”

所以,你可以在这个琐碎的,人为的案例中看到,一个命令可以满足两个规则,但两个规则是相互独立的。来自西海岸的1200美元订单通知Frank和Sally。当弗兰克不再担心时,他只会简单地将他的规则从汤中拉出来。

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

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

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

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

答案 3 :(得分:19)

我见过的规则引擎最大的专业是它让业务规则所有者实现业务规则,而不是将责任放在程序员身上。即使您有一个敏捷的流程,您不断获得利益相关方的反馈并进行快速迭代,但仍然无法达到通过让业务规则实施的人员实现的效率水平。

此外,如果规则嵌入代码中,则不能强调删除可能由简单规则更改导致的重新编译 - 重新测试 - 重新部署周期的值。通常有几个团队参与将祝福放在构建上,使用规则引擎可以使大部分内容变得不必要。

答案 4 :(得分:12)

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

有些程序员不喜欢学习太多东西。规则引擎和你放入它们的规则,以及实现它们的东西,可能有点毛茸茸。虽然一个好的系统可以很容易地处理生病和扭曲的逻辑网络(或经常是不合逻辑的),但它并不像编写一堆if语句那么简单(无论一些简单的规则引擎做什么)。规则引擎为您提供了处理规则关系的工具,但您仍然必须能够想象所有这些在您的脑海中。有时候就像生活在电影巴西中一​​样。 :)

答案 5 :(得分:8)

它(与其他一切一样)取决于您的应用程序。对于某些应用程序(通常是那些永远不会改变或者规则在实际常量上最好的应用程序,即不会在eons中显着变化,例如物理属性和公式),使用规则引擎没有意义,它只是引入了额外的复杂性,并要求开发人员拥有更大的技能。

对于其他应用程序,这确实是一个好主意。例如,订单处理(订单是从发票到处理货币交易的任何东西),不时地对某些相关法律或代码(在司法意义上)进行一分钟更改,要求您满足新的要求(例如销售税) ,经典)。 而不是试图强迫你的旧应用程序进入这种突然你必须考虑销售税的新情况,而不是之前的情况,更容易调整你的规则集而不是干涉潜在的大你的代码集。

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

答案 6 :(得分:5)

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

答案 7 :(得分:3)

“但实际上,有多少应用确实有很多变化?”

老实说,我所处理的每个应用都经历了从概念到部署之后的严格工作流和/或逻辑变化。这是“维护”编程的首要原因......

现实是,你无法预先考虑所有事情,因此敏捷过程的原因。此外,在测试中发现BA之前,BA似乎总是错过一些重要的东西。

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

答案 8 :(得分:2)

规则引擎是可配置应用程序的胜利,如果可以避免,您不希望自定义构建。他们也擅长集中大量规则和算法,例如Rete等算法可以快速匹配大型规则集。

答案 9 :(得分:2)

已经有很多好的答案,但想补充几点:

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

答案 10 :(得分:1)

我认为规则,流程和数据引擎(a.k.a。数据库)基本上是相似的。但是,出于某种原因,我们从不说持久化子系统的黑盒子坏了。

其次,从我的POV来看,贫困模型不是实施行为中的轻微模型,它是行为本身中的轻量级模型。描述域模型对象中可用行为的实际方法不必由对象本身完成。

答案 11 :(得分:0)

我在规则引擎方面的经验最大的复杂性是:

    来自OOP POV的
  1. 在重构影响它们的代码时,重构和测试用声明性语言编写的规则是一件非常痛苦的事。
  2. 我们应该经常考虑规则的执行顺序,这些规则在有很多规则时会变得一团糟。
  3. 一些小的更改可能会触发导致生产错误的规则的错误行为。在实践中,并不总是能够预先覆盖所有测试的情况。
  4. 规则改变其他对象中使用的对象也会增加复杂性,导致开发人员将其分解为各个阶段。