Drools是爲Java量身定製的基於Charles Forgy的RETE算法的規則引擎的實現。具備了OO接口的RETE,使得商業規則有了更天然的表達。html
Rule是什麼呢?java
一條規則是對商業知識的編碼。一條規則有 attributes ,一個 Left Hand Side ( LHS )和一個 Right Hand Side ( RHS )。Drools 容許下列幾種 attributes : salience , agenda-group , no-loop , auto-focus , duration , activation-group 。node
規則的 LHS 由一個或多個條件( Conditions )組成。當全部的條件( Conditions )都知足併爲真時, RHS 將被執行。 RHS 被稱爲結果( Consequence )。 LHS 和 RHS 相似於算法
if(<LHS>){api
<RHS>網絡
}maven
下面介紹幾個術語:ide
對新的數據和被修改的數據進行規則的匹配稱爲模式匹配( Pattern Matching )。進行匹配的引擎稱爲推理機( Inference Engine )。被訪問的規則稱爲 ProductionMemory ,被推理機進行匹配的數據稱爲 WorkingMemory 。 Agenda 管理被匹配規則的執行。推理機所採用的模式匹配算法有下列幾種: Linear , RETE , Treat , Leaps 。這裏注意加紅的地方,對數據的修改也會觸發從新匹配,即對 WorkingMemory中的數據進行了修改。函數
而後規則引擎大概是這個樣子的:oop
這個圖也很好理解,就是推理機拿到數據和規則後,進行匹配,而後把匹配的規則和數據傳遞給Agenda。
規則引擎實現了數據同邏輯的徹底解耦。規則並不能被直接調用,由於它們不是方法或函數,規則的激發是對 WorkingMemory 中數據變化的響應。結果( Consequence ,即 RHS )做爲 LHS events 徹底匹配的 Listener 。
數據被 assert 進 WorkingMemory 後,和 RuleBase 中的 rule 進行匹配(確切的說應該是 rule 的 LHS ),若是匹配成功這條 rule 連同和它匹配的數據(此時就叫作 Activation )一塊兒被放入 Agenda ,等待 Agenda 來負責安排激發 Activation (其實就是執行 rule 的 RHS ),上圖中的菱形部分就是在 Agenda 中來執行的, Agenda 就會根據衝突解決策略來安排 Activation 的執行順序。
下面附上drools規則引擎的執行過程
參考連接:Rete Algorithm
rete在拉丁文裏是net network的意思,這個算法由 Charles Forgy 博士在他的博士論文裏提到。
這個算法能夠分爲兩個部分,一個是如何編譯規則,一個是如何執行。原話(The Rete algorithm can be broken into 2 parts: rule compilation and runtime execution.)
rule compilation 就是如何經過對全部規則進行處理,生成一個有效的辨別網絡。而一個辨別網絡,則對數據進行過濾,使數據一步步往下傳送。數據剛進入網絡,有不少的匹配條件,這裏能夠理解爲:邏輯表達式爲true or false,而後在網絡裏往下傳遞的時候,匹配的條件愈來愈少,最後到達一個終止節點。
在這個論文裏Dr Charles描述了這麼幾個節點,Node:
參考連接:Rete Algorithm
rete在拉丁文裏是net network的意思,這個算法由 Charles Forgy 博士在他的博士論文裏提到。
這個算法能夠分爲兩個部分,一個是如何編譯規則,一個是如何執行。原話(The Rete algorithm can be broken into 2 parts: rule compilation and runtime execution.)
rule compilation 就是如何經過對全部規則進行處理,生成一個有效的辨別網絡。而一個辨別網絡,則對數據進行過濾,使數據一步步往下傳送。數據剛進入網絡,有不少的匹配條件,這裏能夠理解爲:邏輯表達式爲true or false,而後在網絡裏往下傳遞的時候,匹配的條件愈來愈少,最後到達一個終止節點。
在這個論文裏Dr Charles描述了這麼幾個節點,Node:
這裏對其中的幾個節點作一下簡單介紹,另外說一下如何運做的。
Drools extends Rete by optimizing the propagation from ObjectTypeNode to AlphaNode using hashing. Each time an AlphaNode is added to an ObjectTypeNode it adds the literal value as a key to the HashMap with the AlphaNode as the value. When a new instance enters the ObjectType node, rather than propagating to each AlphaNode, it can instead retrieve the correct AlphaNode from the HashMap,thereby avoiding unnecessary literal checks.)
全部通過ObjectTypeNode的對象都會走到下一個節點,下一個節點能夠是下面的幾種:AlphaNodes, LeftInputAdapterNodes and BetaNodes。後面兩個節點是AlphaNodes節點的一些變種,AlphaNodes節點是用來判斷一些條件的。能夠理解爲一些邏輯表達式的計算。
下面開始上圖:
這裏列了一些後面的一些例子須要用到的maven依賴
<!--kie api 構建kie虛擬文件系統,關聯decisiontable和drl文件,很關鍵 -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
</dependency>
<!-- 規則引擎核心包,裏面包含了RETE引擎和LEAPS 引擎-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<!-- 決策表依賴-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
</dependency>
咱們通常用到的也就這兩種形式,一個是drl文件,是drools規則引擎提供的最原生的方式,語法很簡單,具體語法見
還有一個是決策表,決策表能夠是xls也能夠是csv,咱們通常用xls比較多。並且好理解。xls就是一個excel文件。ps:在使用的過程當中,遇到不少坑,其中一個最大的坑是mac系統的問題,這裏後面會安利。
首先來看下drl文件,這個在第2條講解node的時候已經提到過了。
舉例:
rule "ageUp12" when
$student: Student(age > 2)
then
$student.ageUp12();
end
rule "nameMax" when
$student: Student(name == "max")
then
$student.nameMax();
retract($student);
end
簡單說明:以第一個rule爲例
第二個例子能夠看到有個retract($student),這裏是用到了drools內部提供的一個函數,具體見後續關於drools語法介紹的博客
決策表就是一個excel文件,能夠是xls(xlsx暫不支持)或者csv是個表格,看上去也很直觀,即使是不懂代碼的人看了也能看懂,不像drl文件那麼多語法。關鍵的一點是:decisiontable也是最終轉成drl文件來讓drools規則引擎來解析執行的。*.xls到*.drl的轉換這個在後面的wiki會說到。
直接上圖吧
這裏能夠暫時忽略那些背景色,只是爲了好區分沒個模塊的做用
這裏忽略文件開始的空行,從有數據的第一行開始解釋說明:
第一行,第一列:RuleSet 第二列。這裏RuleSet能夠省略的,累似drl文件中的package
第二行,第一列:Import 第二列具體的java類,這裏和drl文件裏的Improt相對應,多個引用類用逗號分隔
第三行,是個對這個決策表的說明
第四行,第一列:RuleTable FirstDecisionTable 這一行很關鍵 指明這是一個決策表,而且下面的幾行都是具體的規則,就比如上面幾行是一些準備條件,下面纔是真正幹活的地方,這裏來個說明
第五行,CONDITION行,這一行能夠有兩種列名:CONDITION ACTION。CONDITION列就是drl裏的辨別條件, ACTION則是具體的操做,即知足前面幾列的CONDITION的條件後,會執行什麼操做,這裏CONDITION必定在ACTION前面,ACTION能夠有多個列, 單個ACTION裏的多個操做用逗號分隔,末尾要加分號結尾這裏很重要,否則會有解析錯誤
第六行,緊挨着CONDITION的一行,能夠在這裏聲明下面要用的到對象,對應drl文件裏的$student:Student()
第七行,是辨別條件邏輯表達式,如:student.getAge()==$param則對應drl裏的age==12這裏$param是對應列每一個單元格的值,而後這裏須要特別說明下,針對於非字符串,如整數,小數等,能夠直接使用$param,可是若是單元格里是字符串,則須要加雙引號。(ps:mac裏的雙引號是斜的,必定要保證是豎着"的)另外,若是有多個值,能夠用逗號隔開,而後能夠用$1,$2提取變量值,如第一個ACTION裏的student.doAction1($1,"$2")
第八行仍然是註釋行,能夠添加每個CONDITON ACTION列的說明。
下面的每一行就是對應的某些條件的取值了。