規則引擎簡單化才能真正實用

 

 今天看到了一篇文章,發現其提到的問題,就是我們已經解決的問題。但是他沒有提到其實規則引擎是可以簡單化的,去掉了衝突推理後的規則引擎,就能夠更好的實現我們日常碰到的各類業務邏輯問題。

而且其不用再去考慮規則優先級,衝突、關聯之類的事情,無需再擔心某處的一個簡單的改變帶來了大量無發確定的後果。實現了易用以及靈活性的完美結合。

 

 今天朋友介紹了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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章