學習JBoss Rules有幾天了,因爲這方面的中文資料較少,所以這幾天都在看官網上的manual。這是一份不錯的教程,我把我看的一些重要的東西翻譯整理了一下,希望可以對想學習JBoss Rules的同學們提供一點幫助。
在開始這份教程之前,我先簡要介紹一下JBoss Rules:
JBoss Rules 的前身是Codehaus的一個開源項目叫Drools。最近被納入JBoss門下,更名爲JBoss Rules,成爲了JBoss應用服務器的規則引擎。
Drools是爲Java量身定製的基於Charles Forgy的RETE算法的規則引擎的實現。具有了OO接口的RETE,使得商業規則有了更自然的表達。
既然JBoss Rules是一個商業規則引擎,那我們就要先知道到底什麼是Rules,即規則。在JBoss Rules中,規則是如何被表示的
Rules
一條規則是對商業知識的編碼。一條規則有 attributes ,一個 Left Hand Side ( LHS )和一個 Right Hand Side ( RHS )。 Drools 允許下列幾種 attributes : salience , agenda-group , no-loop , auto-focus , duration , activation-group 。
< attribute > < value >
when
< LHS >
then
< RHS >
end
規則的 LHS 由一個或多個條件( Conditions )組成。當所有的條件( Conditions )都滿足併爲真時, RHS 將被執行。 RHS 被稱爲結果( Consequence )。 LHS 和 RHS 類似於:
< RHS >
}
規則可以通過 package 關鍵字同一個命名空間( namespace )相關聯;其他的規則引擎可能稱此爲規則集( Rule Set )。一個 package 聲明瞭 imports , global 變量, functions 和 rules 。
對新的數據和被修改的數據進行規則的匹配稱爲模式匹配( Pattern Matching )。進行匹配的引擎稱爲推理機( Inference Engine )。被訪問的規則稱爲 ProductionMemory ,被推理機進行匹配的數據稱爲 WorkingMemory 。 Agenda 管理被匹配規則的執行。推理機所採用的模式匹配算法有下列幾種: Linear , RETE , Treat , Leaps 。
Drools 採用了 RETE 和 Leaps 的實現。 Drools 的 RETE 實現被稱爲 ReteOO ,表示 Drools 對 Rete 算法進行了加強和優化的實現。
一條規則的 LHS 由 Conditional Element 和域約束( Field Constraints )。下面的例子顯示了對一個 Cheese Fact 使用了字面域約束( Literal Field Constraint )
when
Cheese( type == " cheddar " )
then
System.out.println( " cheddar " );
end
上面的這個例子類似於:
if ( cheese.getType().equals( " cheddar " ) {
System.out.println( " cheddar " );
}
}
<!--[if !vml]--> <!--[endif]-->
規則引擎實現了數據同邏輯的完全解耦。規則並不能被直接調用,因爲它們不是方法或函數,規則的激發是對 WorkingMemory 中數據變化的響應。結果( Consequence ,即 RHS )作爲 LHS events 完全匹配的 Listener 。
當 rules 被加入 Productioin Memory 後, rules 被規則引擎用 RETE 算法分解成一個圖:
當 Facts 被 assert 進入 WorkingMemory 中後,規則引擎找到匹配的 ObjectTypeNode ,然後將此 Fact 傳播到下一個節點。 ObjectTypeNode 擁有一塊內存來保存所有匹配的 facts 。在我們的例子中,下一個節點是一個域約束( Field Constraint ), type = = “cheddar” 。如果某個 Cheese 對象的類型不是“ cheddar ”,這個 fact 將不會被傳播到網絡的下一個節點。如果是“ cheddar ”類型,它將被記錄到 AlphaNode 的內存中,並傳播到網絡的下一個節點。 AlphaNode 是古典 RETE 術語,它是一個單輸入 / 單輸出的節點。最後通過 AlphaNode 的 fact 被傳播到 Terminal Node 。 Terminal Node 是最終節點,到此我們說這條規則被完全匹配,並準備激發。
當一條規則被完全匹配,它並沒有立刻被激發(在 RETE 中是這樣,但在 Leaps 中它會立刻被激發)。這條規則和與其匹配的 facts 將激活被放入 Agenda ,由 Agenda 來負責安排激發 Activations (指的是 rule + the matched facts )。
下面的圖很清楚的說明了 Drools 規則引擎的執行過程:
數據被 assert 進 WorkingMemory 後,和 RuleBase 中的 rule 進行匹配(確切的說應該是 rule 的 LHS ),如果匹配成功這條 rule 連同和它匹配的數據(此時就叫做 Activation )一起被放入 Agenda ,等待 Agenda 來負責安排激發 Activation (其實就是執行 rule 的 RHS ),上圖中的菱形部分就是在 Agenda 中來執行的, Agenda 就會根據衝突解決策略來安排 Activation 的執行順序。
import java.util.List
import com.sample.Cheese
global List cheeses
function void exampleFunction(Cheese cheese) {
System.out.println( cheese );
}
rule “A Cheesy Rule”
when
cheese : Cheese( type == " stilton " )
then
exampleFunction( cheese );
cheeses.add( cheese );
end