这是用户在 2024-7-4 10:06 为 https://martinfowler.com/bliki/RulesEngine.html 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

Rules Engine

7 January 2009

Should I use a Rules Engine?
我应该使用规则引擎吗?

A rules engine is all about providing an alternative computational model. Instead of the usual imperative model, which consists of commands in sequence with conditionals and loops, a rules engine is based on a Production Rule System. This is a set of production rules, each of which has a condition and an action - simplistically you can think of it as a bunch of if-then statements.
规则引擎提供了一种替代的计算模型。它不是通常的命令式模型,即由顺序的命令、条件和循环组成,而是基于生产规则系统。这是一组生产规则,每条规则都有一个条件和一个动作——简单来说,你可以把它看作是一堆 if-then 语句。

The subtlety is that rules can be written in any order, the engine decides when to evaluate them using whatever order makes sense for it. A good way of thinking of it is that the system runs through all the rules, picks the ones for which the condition is true, and then evaluates the corresponding actions. The nice thing about this is that many problems naturally fit this model:
微妙之处在于,规则可以以任何顺序编写,引擎会根据自己的逻辑决定何时评估它们。一个很好的思考方式是,系统会遍历所有规则,选择条件为真的那些规则,然后执行相应的动作。这样做的好处是,许多问题很自然地符合这个模型:

  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;

A rules engine is a tool that makes it easier to program using this computational model. It may be a complete development environment, or a framework that can work with a traditional platform. Most of what I've seen in recent years are tools that are designed to fit in with an existing platform. At one time there was the notion of building an entire system using a tool like this, but now people (wisely) tend to use rule engines just for the sections of a system. The production rule computational model is best suited for only a subset of computational problems, so rules engines are better embedded into larger systems.
规则引擎是一种工具,它使基于这种计算模型的编程变得更加容易。它可能是一个完整的开发环境,或者是一个可以与传统平台配合使用的框架。近年来我见过的大多数工具都是设计用来融入现有平台的。曾经有一段时间,人们考虑过使用这样的工具来构建整个系统,但现在(明智地)人们倾向于只将规则引擎用于系统的一部分。生产规则计算模型最适合于计算问题的一小部分,因此规则引擎最好嵌入到更大的系统中。

You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions. But mostly when people refer to "rules engine" they mean a product built specifically to help you build and run a rules engine. Techniques to specify rules can vary from an API for people to describe rules as Java objects, a DSL to express rules, or a GUI that allows people enter rules. More efficient execution engines help to quickly evaluate conditions on hundreds of rules using specialized algorithms (such as the Rete algorithm).
你可以自己构建一个简单的规则引擎。你所需要的就是创建一堆带有条件和动作的对象,将它们存储在一个集合中,然后遍历它们来评估条件并执行动作。但当人们提到“规则引擎”时,他们通常指的是专门用来帮助你构建和运行规则引擎的产品。指定规则的技巧可以各不相同,包括让人们用 Java 对象描述规则的 API、用于表达规则的领域特定语言(DSL),或者允许人们输入规则的图形用户界面。更高效的执行引擎则利用专门的算法(如 Rete 算法)快速评估数百条规则的条件。

An important property of rule engines is chaining - where the action part of one rule changes the state of the system in such a way that it alters the value of the condition part of other rules. Chaining sounds appealing, since it supports more complex behaviors, but can easily end up being very hard to reason about and debug.
规则引擎的一个重要特性是链式调用——其中一条规则的动作部分会以某种方式改变系统状态,从而影响其他规则的条件部分的值。链式调用听起来很有吸引力,因为它支持更复杂的行为,但很容易变得难以理解和调试。

I've run into a few cases where people have made use of rules engine products, and each time things don't seem to have worked out well (disclaimer: I'm not a statistically valid sample). Often the central pitch for a rules engine is that it will allow the business people to specify the rules themselves, so they can build the rules without involving programmers. As so often, this can sound plausible but rarely works out in practice.
我遇到过几次人们使用规则引擎产品的情况,但每次似乎都没有取得很好的效果(免责声明:我并不是一个具有统计学代表性的样本)。通常,规则引擎的核心卖点是它能让业务人员自己定义规则,因此他们可以在不涉及程序员的情况下构建规则。就像很多情况下一样,这听起来可能合理,但在实践中很少能成功实现。

Even so, there's still value in a BusinessReadableDSL, and indeed this is an area where I do see value in this computational model. But here too lie dragons. The biggest one is that while it can make sense to cast your eyes down a list of rules and see that each one makes sense, the interaction of rules can often be quite complex - particularly with chaining. So I often hear that it was easy to set up a rules system, but very hard to maintain it because nobody can understand this implicit program flow. This is the dark side of leaving the imperative computational model. For all the faults of imperative code, it's relatively easy to understand how it works. With a production rule system, it seems easy to get to a point where a simple change in one place causes lots unintended consequences, which rarely work out well.
即便如此,BusinessReadableDSL 仍有其价值,事实上,我确实看到这种计算模型在这方面有其价值。但这里也潜藏着问题。最大的问题是,虽然你可以通读规则列表,确保每一项都有意义,但规则之间的交互往往非常复杂——尤其是当涉及到链式规则时。所以我经常听到这样的说法:建立规则系统很容易,但维护起来却很难,因为没有人能理解这种隐含的程序流程。这就是离开命令式计算模型的阴暗面。尽管命令式代码存在诸多问题,但相对来说,理解其工作原理较为容易。在生产规则系统中,似乎很容易出现一处简单的改动就会引发很多意想不到的后果,而这些后果往往不会带来好的结果。

I haven't spent enough time with these systems to get a sense of what heuristics we should follow to keep this implicit behavior under control.
我还没有花足够的时间来研究这些系统,以了解我们应该遵循哪些启发式规则来控制这种隐性行为。

  • It does seem that it's important to limit the number of rules, indeed any system with enough rules to need sophisticated algorithms to get good performance probably has too many rules to be understood.
    确实,限制规则的数量似乎很重要,因为任何需要复杂算法才能获得良好性能的系统可能都包含了太多难以理解的规则。
  • Be very careful how you use chaining, often its best to organize your rules to limit or even eliminate chaining
    使用链接时要非常小心,通常最好组织你的规则以限制甚至消除链接
  • As in many places, testing is often undervalued here, but implicit behavior makes testing more important - and it needs to be done with production data.
    在这里,如同许多地方一样,测试往往被低估,但隐含的行为使得测试变得更加重要——而且需要用生产数据来进行。
  • While building a rules system, I'd look to do things that would cause EarlyPain with modifications of the rule base.
    在构建规则系统时,我会寻求做一些事情,这些事情会在规则库修改时引发早期痛苦。

All of these lead me to think that there's a lot to be said for avoiding rules engine products. The basic idea of production rules is very simple. In order to keep the implicit behavior under control you also need to limit the number of rules by keeping the rules within a narrow context. This would argue for a more domain specific approach to rules, where a team builds a limited rules engine that's only designed to work within that narrow context. Certainly if you're thinking of using a rules engine I'd suggest prototyping with both a product and a hand-rolled domain specific approach so you can get a good feel for how they would compare.
所有这些都让我认为,避免使用规则引擎产品是有其道理的。生产规则的基本思想非常简单。为了控制隐性行为,你也需要限制规则的数量,将其保持在狭窄的上下文中。这将倾向于采用更特定于领域的规则方法,让团队构建一个仅设计用于在该狭窄上下文中工作的有限规则引擎。当然,如果你正在考虑使用规则引擎,我建议你用产品和手工定制的特定领域方法进行原型设计,以便了解它们如何相比较。

For more information on building your own simple rules engine, including a couple of toy examples, see the Production Rules System chapter of my DSL book.