什么是规则引擎? - martinfowler


规则引擎是关于提供一个替代的计算模型。规则引擎不是通常的命令式模型,它是由带有条件和循环的顺序的命令组成的,而是基于生产规则系统的。这是一组生产规则,每个规则都有一个条件和一个动作--简单地说,你可以把它看成是一堆if-then语句。

微妙之处在于,规则可以以任何顺序编写,引擎决定何时使用任何有意义的顺序来评估它们。一个好的思考方式是,系统运行所有的规则,挑选出条件为真的规则,然后评估相应的行动。这样做的好处是,许多问题都自然而然地符合这个模型。

 if car.owner.hasCellPhone then premium += 100;
  if car.model.theftRating > 4 then premium += 200;
  if car.owner.livesInDodgyArea && car.model.theftRating > 2 
     then premium += 300;

规则引擎是一种工具,它使使用这种计算模型进行编程变得更加容易。它可能是一个完整的开发环境,也可能是一个可以与传统平台一起工作的框架。近年来,我所看到的大多数都是旨在与现有平台相适应的工具。曾几何时,有一种使用这样的工具构建整个系统的概念,但现在人们(明智地)倾向于只在系统的部分使用规则引擎。生产规则的计算模型只适合于计算问题的一个子集,所以规则引擎最好嵌入到更大的系统中。
你可以自己建立一个简单的规则引擎。你所需要的只是创建一堆带有条件和动作的对象,把它们存储在一个集合中,然后通过它们来评估条件和执行动作。但大多数情况下,当人们提到 "规则引擎 "时,他们指的是专门用来帮助你建立和运行规则引擎的产品。指定规则的技术可以是不同的,包括让人们把规则描述成Java对象的API,表达规则的DSL,或者允许人们输入规则的GUI。更有效的执行引擎有助于使用专门的算法(如Rete算法)快速评估数百条规则的条件。
 
重要特点
规则引擎的一个重要属性是链式,即一个规则的动作部分改变了系统的状态,从而改变了其他规则的条件部分的值。链式听起来很吸引人,因为它支持更复杂的行为,但是很容易就会导致推理和调试的困难。

我遇到过一些人们使用规则引擎产品的案例,每次事情似乎都不太顺利(免责声明:我不是一个统计学上的有效样本)。通常情况下,规则引擎的核心主张是,它将允许业务人员自己指定规则,因此他们可以在不涉及程序员的情况下建立规则。就像很多时候一样,这听起来很有道理,但在实践中却很少发挥作用。

即便如此,BusinessReadableDSL还是有价值的,而且这也是我看到这种计算模型的价值所在。但是这里也有一些问题。最大的问题是,虽然把目光投向规则列表,看到每一条规则都是有意义的,但规则的交互往往是相当复杂的--特别是在连锁的情况下。所以我经常听到有人说,建立一个规则系统很容易,但要维护它却非常困难,因为没有人能够理解这种隐含的程序流程。这就是离开命令式计算模型的黑暗面。对于命令式代码的所有缺点,要理解它的工作原理是相对容易的。对于一个生产型的规则系统,似乎很容易达到这样的程度:一个地方的简单改变会导致很多意外的后果,而这些后果很少会有好结果。
 
以下是注意点

  • 看起来限制规则的数量确实很重要,事实上,任何系统如果有足够多的规则,需要复杂的算法来获得良好的性能,可能有太多的规则被理解。
  • 要非常小心你如何使用链式,通常最好是组织你的规则来限制甚至消除链式。
  • 和许多地方一样,测试在这里经常被低估,但隐性行为使得测试更加重要--而且需要用生产数据进行测试。
  • 在建立一个规则系统的时候,我希望做一些会导致EarlyPain的事情,对规则基础进行修改。

 
所有这些都让我觉得,避免使用规则引擎产品有很多好处。生产规则的基本理念非常简单。为了控制隐含的行为,你还需要通过将规则保持在一个狭窄的范围内来限制规则的数量。这就要求对规则采取更具体的领域方法,即一个团队建立一个有限的规则引擎,只在该狭窄的环境中工作。当然,如果你正在考虑使用一个规则引擎,我建议用一个产品和一个手工滚动的特定领域的方法进行原型设计,这样你就可以很好地感觉到它们之间的比较。