规则引擎-利弊


70

我正在审核使用规则引擎的项目。简而言之,这是一种从应用程序代码外部化业务逻辑的方法。

这个概念对我来说是全新的,对此我持怀疑态度。听到人们谈论贫血领域模型后过去几年中的之后,我对规则引擎方法提出了质疑。在我看来,它们似乎是弱化域模型的好方法。例如,说我正在做一个Java Webapp,与规则引擎进行交互。然后,我决定要拥有一个基于相同域的Android应用。除非我也希望Android应用程序也能与Rule Engine交互,否则我将不得不错过任何已编写的业务逻辑。

因为我还没有与他们的任何经验,只是出于好奇,我很想知道使用规则引擎的优缺点?我能想到的唯一优点是,您无需为了更改某些业务规则而重新构建整个应用程序(但实际上,有多少应用程序确实具有许多更改?)。但是使用规则引擎来解决该问题对我来说听起来像是在band弹枪伤口上贴上创可贴。

更新-自从撰写本文以来,上帝本人马丁·福勒(Martin Fowler)就在博客中发表有关使用规则引擎的信息


您是否正在研究任何第三方产品,或者打算推出自己的产品?
Michael Kniskern

3
那是Martin Fowler的精彩文章,谢谢!
乔恩·昂斯托特

您是对的-他们非常反对OO。它们来自OO并不普遍的时代(部分解释了这一点),但是是的,他们非常想使用您所说的“贫乏”的记录/值对象。这不一定是一件坏事,但这是事实。如果您不喜欢,则根本不会喜欢规则引擎。
Michael Neale 2010年

我还将检查一个人是否真正想要(前向链接)规则引擎,或者一个人是否真正想要Prolog或更简单的Datalog的语义清晰的逻辑程序(从某种意义上说:至少一个人首先知道它们所计算的内容)(或可以进入更为稀缺的地区并查看交易逻辑)。如果要响应(“只要数据库中发生任何更改,就执行任何操作!”),那么将Tuplespace / Lindaspace实现与$ PREFERRED_LANGUAGE中的旧OO编程链接在一起,可能是值得的。
David Tonhofer 2013年

Answers:


39

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

还有另一类业务规则:决策。例如,一家保险公司可能需要对承保申请人的风险进行分类并得出保费。您可以将这些类型的业务规则放在您的域模型中,但是通常需要针对此类情况做出集中决策,并且实际上非常适合面向服务的体系结构。这确实引出了为什么要使用规则引擎而不是系统代码的问题。规则引擎可能是更好的选择,而负责决策的业务规则会随时间而变化(正如其他一些答案所指出的那样)。

规则引擎通常允许您在不重新启动系统或部署新的可执行代码的情况下更改规则(无论您从供应商那里得到什么承诺,请确保您在非生产环境中测试更改,因为即使规则引擎无缺陷, ,人类仍在改变规则)。如果您在考虑“我可以通过使用数据库来存储变化的值来做到这一点”,那么您是对的。规则引擎不是一个神奇的盒子,它可以做一些新的事情。它旨在成为提供更高抽象级别的工具,因此您可以将精力集中在重塑轮子上。许多供应商通过允许您创建模板来使这一步骤更进一步,以便业务用户可以填充空白而不是学习规则语言。

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


1
我迟到两年了,所以如果您仍然在Aaron身边,能否描述一下上述好处(无需重新启动系统以进行更改;业务规则的抽象,去耦和重用)有何不同?引擎,而不只是一般的SOA架构的好处?换句话说,规则引擎不是SOA的子集吗?如果是,那么规则引擎有什么明显的好处,而不是简单地部署以命令式代码编写的SOA服务?
戴夫·西姆斯

1
SOA体系结构是规则引擎决策的良好生态系统。引擎可以根据系统需求将呼叫路由到不同的服务。如果没有管理员,管理员将手动配置系统以遵循另一条路径。
neontapir 2011年

1
我列出的许多好处都与SOA架构有关。规则引擎提供的一些好处(不一定来自SOA架构)是声明性代码,也是企业所有者更改规则的一种方式,例如减少触发手动审查的金额。并非非规则引擎解决方案无法实现这些功能,而是规则引擎尝试开箱即用地提供这些功能。
亚伦

1
Martin Fowler的最新博客文章深入探讨了如何将代码重构为数据+规则引擎:重构为自适应模型
jnm2

27

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

我已经看到了在我工作的生产环境中运行的著名商业Rete规则引擎的两个应用程序。我会认为一个成功,而另一个则失败。

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

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

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

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

我认为使用对象作为划分引擎空间的一种方法没有错。在我看来,将行为嵌入到专用规则引擎的对象中似乎可以。当规则引擎要求不属于其对象的状态才能正确触发时,问题就会袭来。但这只是设计困难的另一个例子。


24

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

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

您可以看到,在这种情况下,如果您有一个很大的AWK文件,并且想要添加另一个“规则”,则可以轻松转到文件底部,添加正则表达式和逻辑,并完成它。具体来说,对于许多应用程序,您不必特别关注其他规则的作用,并且这些规则之间不会真正互操作。

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

例如,Frank对订单总额超过1000美元的订单感兴趣,因此他将自己感兴趣的规则系统放入订单中。“如果order.total> 1000 THEN则发送电子邮件给Frank”。

同时,Sally希望从西海岸获得所有订单:“如果IF order.source =='WEST_COAST'然后向Sally发送电子邮件”。

因此,在这种琐碎的,人为的情况下,您可以看到一个订单可以同时满足两个规则,但是两个规则彼此独立。西海岸的1200美元订单通知了Frank和Sally。当弗兰克不再关心时,他只需从汤中撤出他的统治即可。

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

现在,很明显,在一个复杂的系统中,可能会发生各种各样的相互关系,这就是为什么整个系统不是“按规则进行”的原因。某个地方的某人将负责规则的制定。但这并不一定会降低该系统可以提供的价值。

请注意,这甚至不涉及专家系统之类的东西,在专家系统中,规则会根据规则可以创建的数据触发,而更简单的规则系统。

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


19

我所见过的规则引擎的最大优点是,它使业务规则所有者可以实现业务规则,而不是让程序员承担责任。即使您有一个敏捷的过程,不断获得利益相关者的反馈并进行快速迭代,也仍然无法达到让制定业务规则的人员也执行它们所能达到的效率水平。

此外,如果规则嵌入在代码中,则在删除可能因简单的规则更改而导致的重新编译-重新测试-重新部署周期时,也不能过分强调此值。通常会有好几个团队参与到构建中来,而使用规则引擎可以使很多事情变得不必要。


1
这招来麻烦。让bis规则所有者将生产规则写入反应性系统(具有非常不清楚的语义和不确定性的行为),而无需与团队其他成员进行测试和协调,这是一个坏主意。最好与开发人员冷静地讨论在适当的地方添加方法或函数。如果需要,请为biz规则所有者提供一种通用的或避免使用脚踏车的特定于域的语言(如今这些语言很容易开发)进行编码。然后,他们可以将其挂接到整个系统中-在对其进行测试之后。biz规则通常不是生产规则!
David Tonhofer 2013年

出现“重新编译-重新测试-重新部署周期”是有原因的,它应该是完全自动化的,因此您只需单击一个按钮即可。
IlliakaillI 2016年

14

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

缺点是某些程序员不喜欢学习太多。规则引擎和您放入规则引擎中的规则以及实现它们的内容可能有点麻烦。尽管一个好的系统可以轻松地处理复杂多变的逻辑网(或者经常是不合逻辑的逻辑网),但是它并不像编码一堆if语句那样简单(无论某些简单明了的规则引擎做什么)。规则引擎为您提供了处理规则关系的工具,但是您仍然必须能够想到所有这些。有时候,就像住在电影《巴西》中一样。:)


8

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

对于其他应用程序,这确实是一个好主意。以订单处理为例(从发票到处理货币交易的各种订单),时不时地对一些相关法律或法规(司法意义上的)进行细微更改,要求您满足新的要求(例如营业税) ,经典)。与其试图使旧应用程序进入这种新情况,而不必像以前那样突然考虑营业税,不如不像以前那样,改编规则集要比在可能的情况下多花点功夫容易得多。您的代码集。

然后,您当地政府的下一项修正案要求在一定条件下报告所有销售情况,而不是您也必须进行添加。最后,您将获得非常复杂的代码,当您转身并希望恢复其中一个规则的效果而又不影响其他所有规则时,将很难管理这些代码。


6

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


3

“但是,实际上,有多少应用程序确实有这么多更改?”

老实说,我开发的每个应用程序都经历了从概念到部署后的整个工作流程和/或逻辑更改。这是“维护”编程的首要原因...

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

规则引擎迫使您将业务逻辑与表示和存储区分开来。此外,如果使用正确的引擎,您的BA可以根据需要添加和删除逻辑。正如克里斯·马拉斯蒂·乔治(Chris Marasti-Georg)所说,这是广管局的责任。不仅如此,它还使广管局能够准确地获得他们的要求。


@贾斯珀:我没有特别提到Drools。还有其他产品。我在另一个地方使用的一个叫做Haley Rules Engine(因为Oracle已经购买了它并退出了市场)。那个特定的引擎具有一个接口,可以编写我们的BA接受过训练的规则。这是非常光滑和快速。由于它的易用性和速度,我们使用它来驱动每个客户对网页上的数据输入的要求。要求由BA直接输入。规则示例为“如果APR大于3.0,则要求附录ABC123”
NotMe,2012年

2

规则引擎在可配置的应用程序上是一个胜利,如果可以避免的话,您就不必进行自定义构建。它们还擅长集中大型规则库,像Rete这样的算法可快速匹配大型规则集。


2

已经有很多好的答案,但想补充一些内容:

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

1

我认为规则,流程和数据引擎(又名数据库)在本质上是相似的。但是,出于某种原因,我们永远不会说对持久性子系统进行黑匣子是不好的。

其次,从我的观点来看,一个贫血的模型并不是一个简单的行为实施模型,而是一个简单的行为本身模型。描述域模型对象中可用行为的实际方法不必由对象本身完成。


0

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

  1. 从OOP POV来看,重构和测试以声明性语言编写的规则确实是一件很痛苦的事情,而同时重构会影响到它们的代码。
  2. 通常,我们应该经常考虑规则的执行顺序,当规则很多时,它们就会变得一团糟。
  3. 一些小的更改可能会触发规则的错误行为,从而导致生产错误。在实践中,并非总是可以通过测试覆盖所有情况。
  4. 对其他对象中使用的对象进行规则更改也会增加复杂性,从而导致开发人员将其分为多个阶段。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.