简单是王道《十、Martin Fowler:应该使用规则引擎吗?》

今天朋友介绍了Martin Fowler刚写的一篇文章。单纯针对规则引擎这种工具来说,有些想法和我们的接近。关于工具,前面的博客中已经讲过两次。下面的文章是从一个侧面提醒我们,工具的使用要非常地谨慎。另外,Martin没有提到的是,当你用了工具实现了系统,也许在很长的一段时间内将无法摆脱噩梦。

以下翻译:

规则引擎提供了一种新的计算模型。和一般的命令模型(带条件和循环的顺序执行指令)不同,它提供了一组产生式规则。每个规则有一个条件和一个操作,简单地说,你可以认为是一堆的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;

规则引擎是工具,它让使用这种计算模型的程序变得更简单了。它也可能是个完整的开发环境,或者是可以和传统的平台一起工作的框架。我这些年看到的大多数都是那种运用在现有的平台上的工具。同时,也有用这样的工具来构建整个系统的思想。不过现在聪明的人士倾向于把规则引擎仅仅作为系统的部分地方。产生式规则计算模型最适用的还是计算问题的一个子集,所以规则引擎最好嵌入到大系统中。

你自己也可以构建简单的规则引擎。要做的是创建一堆带有条件和操作的对象,把它们存在一个集合中,然后运行它们,评估条件执行操作。通用的规则引擎提供了方法来描述规则,执行得更加有效。指定规则的技巧可以使人们不用考虑API,而是这样来描述规则,java对象、表达规则的DSL、或者录入规则的GUI。更有效率的执行引擎使用指定的算法(如Rete算法)来快速评估数以百计的规则上的条件。

我遇到过一些使用规则引擎的案例,每次似乎都不是顺顺利利的(也许我不是一个好的样本)。规则引擎经常提到的要点是,允许业务人员自己来制定规则,所以不需要程序员的参与了。这听上去是是而非而且实际上很少是这样的。

虽然如此,在BusinessReadableDSL方面还是有价值的,其实这也是这种计算模型中我觉得有价值的地方。但是这里存在着很多风险。最大的一个是当你低头关注一系列规则时,规则的交互经常变得异常复杂,特别是存在关联,例如规则的操作改变了其他有关联的规则条件的状态。我经常听到这样的说法,规则系统很容易上手,但是很难维护,因为没有人可以理解其中隐藏的程序流。这是抛弃命令计算模型带来的问题。命令代码的问题相对容易理解它是如何工作的。而一个产生式规则系统,好像更容易带来一个问题,就是某处的一个简单的改变带来了大量无发确定的后果,所以很少会顺顺利里的。

我没有花费足够的时间在这些系统上面,只是有个感觉,我们应该遵循一些点:

1. 规则数量要少,否则会带来效率和理解上的问题;

2. 我倾向于规则见要少关联;

3. 测试问题;

4. 。。。

上面这些让我觉得要避免通用的规则系统。产生式规则的基本思想是很简单的。为了更好的控制,要显得规则在一个很窄的上下文中。当然如果你想使用规则引擎,我建议做个验证,通用的规则引擎和手工的域的特定实现,你可以比较一下找找感觉。

以下原文:

 

RulesEngine design 7 January 2009 Reactions

 

Should I use a Rules Engine?

A rules engine is all about providing an alternative computational model. Instead of the usual imperative model, commands in sequence with conditionals and loops, it provides a list of production rules. Each rule has a condition and an action - simplistically you can think of it as a bunch of if-then statements.

The subtlety is that rules can be written in any order and the system can evaluate them in any order. 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. General rules engines offer ways to describe the rules, and more efficient execution. 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).

I've run into a few cases where people have made use of rule engines, 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 - where the actions of rules changes the state on which other rules' conditions are based. 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.

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.
  • Similarly I'm inclined to think one should be wary of rules that do a lot of 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.

Both of these lead me to think that there's a lot to be said for avoiding more general rules systems. 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 general rules engine and a hand-rolled domain specific approach so you can get a good feel for how they would compare.

你可能感兴趣的:(职场,规则引擎,休闲,王道,Martin,Fowler)