2008-10-30 148 views
61

我正在審計一個項目,該項目使用所謂的Rules Engine。簡而言之,它是從應用程序代碼中外化業務邏輯的一種方法。規則引擎 - 優缺點

這個概念對我來說是全新的,我很懷疑它。在過去幾年中聽到人們談論Anemic Domain Models之後,我在質疑規則引擎方法。對我來說,他們似乎是減弱域模型的好方法。例如,我正在做一個java webapp與一個規則引擎交互。然後我決定我想要一個基於相同域的Android應用程序。除非我想讓Android應用程序與規則引擎進行交互,否則我將不得不錯過已寫入的任何業務邏輯。

由於我還沒有任何經驗,只是好奇心,我有興趣聽說利弊是在使用規則引擎?我能想到的唯一一個專業人員是,您不需要重新構建整個應用程序來改變一些業務規則(但真的,有多少應用程序真的有這麼多的改變?)。但是使用規則引擎來解決這個問題對我來說就像是在霰彈槍傷口上施加一個創可貼。

更新 - 自寫這篇文章以來,神本人Martin Fowler擁有blogged about using a Rules engine

+0

您是否正在尋找任何第三方產品,或者您打算推出自己的產品? – 2008-10-31 16:59:01

+3

這是Martin Fowler的一篇很棒的文章,謝謝! – 2009-09-16 21:07:00

+0

你是對的 - 他們非常反OO。他們來自OO不常見的情況(這部分解釋了它),但是他們非常希望與您說的「貧血」的記錄/價值對象一起工作。這不一定是壞事,但它就是這樣。如果你不喜歡這樣 - 你不會喜歡規則引擎。 – 2010-11-08 00:42:54

回答

36

我見過的大多數規則引擎被系統代碼視爲黑盒子。如果我要建立一個領域模型,我可能希望某些商業規則是領域模型的內在特徵,例如告訴我對象何時具有無效值的業務規則。這允許多個系統共享域模型而不需要複製業務邏輯。我可以讓每個系統使用相同的規則服務來驗證我的域模型,但這似乎削弱了我的域模型(正如問題中指出的那樣)。爲什麼?因爲我始終依靠系統程序員來決定何時應該執行業務規則(通過調用規則服務),而不是始終在所有系統上始終執行業務規則。如果域模型對您來說完全填充,這可能不會成爲問題,但如果您要處理在其生命週期中更改域模型中的值的用戶界面或系統,則可能會出現問題。

還有另一類業務規則:決策制定。例如,一家保險公司可能需要對承保申請人的風險進行分類並收取保費。您可以將這些類型的業務規則放置在您的域模型中,但對於這種場景的集中決策通常是可取的,實際上,它們非常適合面向服務的體系結構。這確實討論了爲什麼使用規則引擎而不是系統代碼。規則引擎可能是更好的選擇的地方是負責決策的業務規則隨着時間的推移而變化(正如其他一些答案指出的那樣)。

規則引擎通常允許您在不重新啓動系統或部署新的可執行代碼的情況下更改規則(無論您從供應商那裏得到什麼承諾,確保您在非生產環境中測試您的更改,因爲即使規則引擎完美無瑕,人類仍在改變規則)。如果你想,「我可以通過使用數據庫來存儲改變的值」,你是對的。規則引擎不是一個能夠做出新事物的神奇盒子。它旨在成爲提供更高抽象級別的工具,因此您可以更少關注重新發明輪子。許多供應商通過讓您創建模板來進一步實現這一目標,以便業務用戶可以填充空白而不是學習規則語言。

關於模板的一個小心謹慎:與編寫沒有模板的規則相比,模板永遠不會花費更少的時間,因爲模板必須至少描述規則。計劃一個更高的初始成本(就像建立一個使用數據庫來存儲更改值的系統,而不是直接在系統代碼中編寫規則一樣) - ROI是因爲您節省了將來維護的系統代碼。

18

我見過的規則引擎最大的特點就是它可以讓業務規則所有者實現業務規則,而不是把責任推給程序員。即使你有一個敏捷的流程,你不斷地從利益相關者那裏得到反饋,並且經歷了快速的迭代,但它仍然不能達到讓制定業務規則的人也能實現的效率水平。

另外,如果規則嵌入代碼中,則不能過分強調刪除可能由簡單規則更改導致的重新編譯重新測試重新部署週期的價值。經常有幾個團隊參與到構建的祝福中,並且使用規則引擎可以使許多不必要的事情發生。

23

規則引擎在某些情況下可以提供很多價值。

首先,許多規則引擎以更具說明性的方式工作。一個非常粗略的例子是AWK,您可以在其中分配正則表達式到代碼塊。當文件掃描器看到正則表達式時,將執行代碼塊。

你可以看到,在這種情況下,如果你有一個大的AWK文件,並且你想添加另一個「規則」,你可以很容易地到文件底部,添加你的正則表達式和邏輯,並完成它。具體而言,對於許多應用程序,您並不特別關心其他規則在做什麼,並且規則並不真正互相操作。

因此,AWK文件變得更像是一個「規則湯」。這種「規則湯」的性質讓人們非常緊張地關注他們的領域,而很少關注系統中可能存在的所有其他規則。

例如,弗蘭克對總價值超過1000美元的訂單感興趣,因此他提出了他感興趣的規則系統。 「如果order.total> 1000那麼電子郵件弗蘭克」。同時,Sally希望來自西海岸的所有訂單:「IF order.source =='WEST_COAST'THEN給Sally發郵件」。

所以,你可以看到在這個微不足道的,人爲的情況下,一個訂單可以同時滿足兩個規則,但是兩個規則都是相互獨立的。來自西海岸的1200美元訂單通知Frank和Sally。當弗蘭克不再擔心的時候,他只是簡單地從湯裏抽出他的排除。

對於很多情況下,這種靈活性可能非常強大。它也可以像這種情況一樣向最終用戶公開最簡單的規則。使用高級表達式和可能輕量級的腳本。

現在,顯然,在一個複雜的系統中可能會發生各種相互關係,這就是爲什麼整個系統不是「完成規則」的原因。有人在某個地方負責規定不會失控。但這並不一定會降低系統所能提供的價值。

注意,這甚至不涉及專家系統,其中規則觸發了規則可以創建的數據,而是更簡單的規則系統。

無論如何,我希望這個例子展示了一個規則系統如何幫助擴大一個更大的應用程序。

8

它(如其他所有)取決於您的應用程序。對於某些應用程序(通常是那些永遠不會改變的規則或規則對現實生活常數最好的應用程序,即不會在非常規條件下發生明顯變化,例如物理屬性和公式),使用規則引擎是沒有意義的,它只是引入了額外的複雜性,並要求開發人員擁有更大的技能。

對於其他應用程序,這真是個好主意。以訂單處理爲例(訂單是從發票到處理貨幣交易的任何事情),每隔一段時間,對某些相關法律或法規(司法意義上)要稍作修改,要求您履行新的要求(例如銷售稅,經典)。 而不是試圖強制你的舊應用程序進入這種新的情況,突然之間你必須考慮銷售稅,而在以前沒有的情況下,更容易適應你的規則集,而不是必須在潛在的大量的代碼。

然後,您當地政府的下一個修訂要求在一定標準內報告所有銷售情況,而不是必須進入並補充說明。最後,你會得到非常複雜的代碼,當你轉身想要恢復其中一個規則的效果,而不會影響所有其他規則時,這將很難管理。

5

到目前爲止,每個人都有對規則引擎非常樂觀,但我建議讀者謹慎。當問題變得更加複雜時,您可能會突然發現整個規則引擎已經變得不合適,或者比使用更強大的語言更復雜。此外,對於許多問題,規則引擎將無法輕鬆檢測到可大大減少評估條件的運行時間和內存佔用量的屬性。我相對較少的情況是我更喜歡規則引擎到依賴注入框架或更動態的編程語言。

3

「但是真的,有多少應用程序真的有這麼多的變化?」

老實說,我所從事的每一個應用程序都經歷了嚴肅的工作流程和/或從概念到邏輯的變化,直到部署完成。這是「維護」編程的首要原因......

現實情況是,您無法事先考慮所有事情,因此也就無法考慮敏捷流程的原因。此外,廣管局似乎總是錯過重要的東西,直到在測試中發現它爲止。

規則引擎強制您真正將演示和存儲的業務邏輯分開。此外,如果使用正確的引擎,您的BA可以根據需要添加和刪除邏輯。正如Chris Marasti-Georg所說,它將責任推到廣管局。但更重要的是,它可以讓廣管局得到他們要求的確切內容。

12

我寫了一個客戶端的規則引擎。最大的勝利是包括所有的利益相關者。引擎可以運行(或重放)查詢並解釋文本中發生了什麼。業務人員可以查看文本說明,並快速指出規則,例外和其他特殊情況中的細微差別。一旦涉及商業方面,驗證就會變得更好,因爲它很容易得到他們的意見。此外,規則引擎可以獨立於應用程序代碼庫的其他部分,因此您可以跨應用程序使用它。

這個騙局是有些程序員不喜歡學得太多。規則引擎和你投入它們的規則,以及實現它們的東西,可能有點多毛。儘管一個好的系統可以很容易地處理病態和扭曲的邏輯網絡(或者經常不合邏輯),但並不像編寫一堆陳述(不管一些頭腦簡單的規則引擎所做的那樣)簡單。規則引擎爲您提供處理規則關係的工具,但您仍然必須能夠想象出所有這些。有時候就像生活在電影巴西。 :)

2

規則引擎是可配置應用程序上的一個勝利,如果可以避免的話,您不希望自定義構建。他們也善於集中規則和算法的大型基礎,如Rete對於快速匹配大型規則集非常有效。

24

我認爲你對貧血域模型的擔憂是有效的。

我見過在生產著名的商業規則Rete算法發動機運行的兩個應用程序,我的工作。我會考慮一個成功,另一個失敗。

的成功應用是決策樹的應用程序,包括的約30個各分〜10棵樹。規則引擎有一個用戶界面,可以讓業務人員維護規則。

不太成功的應用程序有〜3000條規則衝擊規則數據庫。當添加新規則時,沒有人知道是否存在衝突規則。對Rete算法有一點了解,並且產品的專業知識已經離開了公司,所以它變成了一個不可觸及和不可修復的黑盒子。部署週期仍受規則更改的影響 - 必須在更改規則時完成完整的迴歸測試。記憶也是一個問題。

我會輕輕一點。當規則集規模適中時,很容易理解變化,就像上面給出的簡單電子郵件示例一樣。一旦規則數量攀升到數百個,我認爲你可能會遇到問題。

我還擔心一個規則引擎成爲應用程序中的單瓶頸。

我沒有看到使用對象作爲劃分規則引擎空間的方式。在遵循私有規則引擎的對象中嵌入行爲對我來說似乎沒有問題。當規則引擎要求狀態不是其對象的一部分才能正常觸發時,問題會觸及你。但這只是設計難度的另一個例子。

2

很多好的答案已,但想補充一兩件事情:

  1. 在自動化任何一個複雜的決定關鍵事迅速成爲你的管理,而不是執行所涉及的邏輯能力。規則引擎無助於此 - 您需要考慮業務規則管理系統具有的規則管理功能。大多數商業和開放源代碼規則引擎已經發展成爲帶有存儲庫的規則管理系統,報告規則使用情況,版本控制等。構建成協調一致的規則集以進行業務決策的規則存儲庫比任一規則更容易管理數千行代碼或規則湯。
  2. 有很多方法可以使用基於規則的聲明式方法。使用規則來管理UI或作爲定義流程的一部分可能非常有效。然而,規則方法的最有價值的用途是自動化業務決策,並將其作爲鬆散耦合的決策服務來實現,這些決策服務採取輸入,執行規則並返回答案 - 一個決定。這些服務可以回答其他服務的問題,例如「這個客戶是一個很好的信用風險」,或者「我應該給這個客戶這個訂單什麼樣的折扣」或者「這個客戶此時最好的交叉銷售是什麼。這些決策服務可以使用規則管理系統非常有效地構建,並允許隨着時間的推移輕鬆整合分析,這是許多決策受益的原因。
1

我見規則,流程和數據引擎(又名數據庫)作爲基本是相似的。但是,由於某種原因,我們從不說黑盒子持久化子系統是不好的。

其次,從我的POV,貧血模型是不是一個在執行行爲的光,它是一個很輕的行爲本身。描述域模型對象中可用行爲的實際方法不必由對象本身完成。

0

從我的規則引擎體驗最大的複雜性在於:

  1. 從OOP POV這是一個真正的痛苦重構並寫入,而你正在重構代碼說明性語言,影響他們的測試規則。
  2. 通常我們應該總是考慮規則的執行順序,當有很多規則時它們會變成一團糟。
  3. 一些細微的變化可能會導致導致生產錯誤的規則行爲不正確。在實踐中,預先覆蓋所有的案例並不總是可能的。
  4. 規則使其他規則中使用的對象變異也會增加複雜性,從而導致開發人員將其分解爲多個階段。