原文链接:https://martinfowler.com/bliki/RulesEngine.html
本文为原文翻译,有条件的还是直接看原文吧。
规则引擎就是要提供替代的计算模型。规则引擎基于生产规则系统,而不是通常的命令性模型,该命令性模型由按顺序排列的命令以及条件和循环组成。这是一组生产规则,每个规则都有一个条件和一个动作-简单来说,您可以将其视为一堆if-then语句。
精妙之处在于规则可以按任何顺序编写,引擎会决定何时使用对顺序有意义的任何方式来评估它们。考虑它的一个好方法是系统运行所有规则,选择条件成立的规则,然后评估相应的操作。这样做的好处是,许多问题自然都适合此模型:
如果car.owner.hasCellPhone,则premium + = 100;
如果car.model.theftRating> 4,则premium + = 200;
如果car.owner.livesInDodgyArea && car.model.theftRating> 2
然后溢价+ = 300;
规则引擎是一种工具,可以更轻松地使用此计算模型进行编程。它可以是完整的开发环境,也可以是可以与传统平台一起使用的框架。近年来,我所见到的大多数都是设计为适合现有平台的工具。曾经有一种想法是使用这样的工具来构建整个系统,但是现在人们(明智地)倾向于仅将规则引擎用于系统的各个部分。生产规则计算模型最适合仅解决一部分计算问题,因此规则引擎可以更好地嵌入到较大的系统中。
您可以自己构建一个简单的规则引擎。您所需要做的就是创建一堆带有条件和动作的对象,将它们存储在一个集合中,然后遍历它们以评估条件并执行这些动作。但是大多数情况下,当人们提到“规则引擎”时,它们是指专门用来帮助您构建和运行规则引擎的产品。指定规则的技术可能有所不同,包括人们将API描述为Java对象的API,表达规则的DSL或允许人们输入规则的GUI。高效的执行引擎有助于使用专门的算法(例如Rete算法)快速评估数百条规则的条件。
规则引擎的重要属性是链接 -一条规则的动作部分以改变其他规则的条件部分的值的方式更改系统状态。链接听起来很吸引人,因为它支持更复杂的行为,但很容易导致很难推理和调试。
我遇到过一些人使用规则引擎产品的情况,但每次情况看起来都做得不好时(免责声明:我不是一个统计有效的样本)。规则引擎的中心点通常是允许业务人员自己指定规则,因此他们可以在不涉及程序员的情况下构建规则。通常,这听起来似乎合理,但实际上却很少解决。
即使这样,BusinessReadableDSL仍然有价值,的确是这个计算模型中有价值的地方。但是这里也有龙。最大的问题是,尽管将您的视线放到一系列规则上并看到每个规则都是有意义的,但规则的交互通常会非常复杂-尤其是使用链接时。所以我经常听到,建立规则系统很容易,但是很难维护它,因为没人能理解这个隐式程序流。这是离开命令式计算模型的黑暗面。对于命令式代码的所有错误,相对容易理解其工作方式。使用生产规则系统,似乎很容易达到一个地方的简单更改会导致很多意想不到的后果,而这种后果很少会奏效。
我没有在这些系统上花费足够的时间来了解我们应该采取什么启发式方法来控制这种隐式行为。
- 似乎很重要的是限制规则的数量,实际上,任何具有足够规则的系统都需要复杂的算法来获得良好的性能,因此可能有太多规则需要理解。
- 要非常小心地使用链接,通常最好是组织规则来限制甚至消除链接
- 在许多地方,测试在这里常常被低估,但是隐式行为使测试变得更加重要-它需要使用生产数据来完成。
- 在构建规则系统时,我希望通过修改规则库来做会导致EarlyPain的事情。
所有这些使我认为避免规矩引擎产品还有很多话要说。生产规则的基本思想非常简单。为了使隐式行为受到控制,您还需要通过将规则保持在狭窄的上下文中来限制规则的数量。这就需要一种针对特定领域的规则方法,其中团队将构建一个有限的规则引擎,该引擎仅旨在在狭窄的环境中工作。当然,如果您正在考虑使用规则引擎,那么我建议您同时使用产品原型和手推特定领域的方法进行原型设计,以便您可以很好地了解它们的比较方式。