什麼是規則引擎? - martinfowler

banq發表於2022-02-10

規則引擎是關於提供一個替代的計算模型。規則引擎不是通常的命令式模型,它是由帶有條件和迴圈的順序的命令組成的,而是基於生產規則系統的。這是一組生產規則,每個規則都有一個條件和一個動作--簡單地說,你可以把它看成是一堆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的事情,對規則基礎進行修改。

 
所有這些都讓我覺得,避免使用規則引擎產品有很多好處。生產規則的基本理念非常簡單。為了控制隱含的行為,你還需要透過將規則保持在一個狹窄的範圍內來限制規則的數量。這就要求對規則採取更具體的領域方法,即一個團隊建立一個有限的規則引擎,只在該狹窄的環境中工作。當然,如果你正在考慮使用一個規則引擎,我建議用一個產品和一個手工滾動的特定領域的方法進行原型設計,這樣你就可以很好地感覺到它們之間的比較。
 

相關文章