Drools是一款基於Java的開源規則引擎,實現了將業務決策從應用程序中分離出來。本文是做爲一個技術角度進行編寫,文采有限,僅供對drools有必定了解,而且想搞清楚drools內部實現原理,並想提高編程技巧的同行學習和指正。web
一、案例算法
一個學校把學生的信息錄入系統中,想找一批籃球苗子進行培養,爲中國體育事業輸送人才。編程
(1)事實:StudentFact對象微信
該對象中存放了學生的基本信息。年級,性別,年齡,身高,身體素質的信息。網絡
(2)篩選規則:SelectStudentRule描述。app
IF:學習
年級是三年級以上,url
性別是男的,spa
年齡小於10歲,.net
身體健壯,
身高170cm以上,
THEN:
這個男孩是一個籃球苗子,須要培養,把該學生的信息存放到籃球苗子的表中
二、rete算法包含的部分
Working-Memory:存放要匹配規則的事實,也就說,存放的是業務對象,即StudentFact對象。
RuleBase:存放的是業務人員制定的形形色色的規則SelectStudentRule。
Pattern-Matcher:業務對象匹配規則的重要部分,也就是業務對象在規則網絡中流動的過程的執行器。即StudentFact匹配SelectStudentRule的過程。
Agenda:一旦一個業務對象匹配了一個規則,會造成該規則和該業務對象的一個議程。即StudentFact要把該學生信息存入籃球苗子表中的事件。
Execution-Engine:業務對象匹配上一個規則後,業務對象執行規則結果的執行器。即將StudentFact信息存放如籃球苗子表中事件的執行器。
三、rete算法的網絡圖
匹配過程:
(1)、匹配過程當中事實在網絡節點中的流轉順序爲A-->B-->C-->D-->E-->F-->G-->H-->I--->規則匹配經過
(2)、從working-Memory中拿出一個待匹配的StudentFact對象,進入根節點而後進行匹配,如下是fact在各個節點中的活動圖:
A節點:拿StudentFact的年級數值進行年級匹配,若是年級符合條件,則把該StudentFact的引用記錄到A節點的alpha內存區中,退出年級匹配。
B節點:拿StudentFact的性別內容進行性別匹配,若是性別符合條件,則把該StudentFact的引用記錄到B節點的alpha內存區中,而後找到B節點左引用的Beta節點,也就是C節點。
C節點:C節點找到本身的左引用也就是A節點,看看A節點的alpha內存區中是否存放了StudentFact的引用,若是存放,說明年級和性別兩個條件都符合,則在C節點的Beta內存區中存放StudentFact的引用,退出性別匹配。
D節點:拿StudentFact的年齡數值進行年齡條件匹配,若是年齡符合條件,則把該StudentFact的引用記錄到D節點的alpha的內存區中,而後找到D節點的左引用的Beta節點,也就是E節點。
E節點:E節點找到本身的左引用也就是C節點,看看C節點的Beta內存區中是否存放了StudentFact的引用,若是存放,說明年級,性別,年齡三個條件符合,則在E節點的Beta內存區中存放StudentFact的引用,退出年齡匹配。
F節點:拿StudentFact的身體數值進行身體條件匹配,若是身體條件符合,則把該StudentFact的引用記錄到D節點的alpha的內存區中,而後找到F節點的左引用的Beta節點,也就是G節點。
G節點:G節點找到本身的左引用也就是E節點,看看E節點的Beta內存區中是否存放了StudentFact的引用,若是存放,說明年級,性別,年齡,身體四個條件符合,則在G節點的Beta內存區中存放StudentFact的引用,退出身體匹配。
H節點:拿StudentFact的身高數值進行身高條件匹配,若是身高條件符合,則把該StudentFact的引用記錄到H節點的alpha的內存區中,而後找到H節點的左引用的Beta節點,也就是I節點。
I節點:I節點找到本身的左引用也就是G節點,看看G節點的Beta內存區中是否存放了StudentFact的引用,若是存放了,說明年級,性 別,年齡,身體,身高五個條件都符合,則在I節點的Beta內存區中存放StudentFact引用。同時說明該StudentFact對象匹配了該規 則,造成一個議程,加入到衝突區,執行該條件的結果部分:該學生是一個籃球苗子。
四、drools源碼,一個事實匹配規則過程的原理介紹
一個Fact經過Session添加到規則網絡中,如何進行規則匹配的大體過程以下:
(1)、經過根結點對象從EntryPointNode的Map集合中找到相應的EntryPointNode對象;
(2)、EntryPointNode對象有一個ObjectTypeNode的Map集合,把fact的class轉化成ClassObjectType,從該集合中找到ObjectTypeNode;
(3)、OjectTypeNode對象的sink屬性引用着這個fact事實的規則網絡;
(4)、從sink屬性中的鏈表中拿出一個alphaNode進行匹配,遞歸遍歷全部alphaNode的子節點(sink屬性),根據alphaNode中的條件對Fact數據進行比較。
==>(向下(子節點)是試圖完整匹配一條規則),若是向下有不匹配的,表示該規則不符合當前fact,退出遞歸,開始向右匹配。
==>(向右(nextRightTupleSinkNode屬性)開始試圖匹配另外一條規則)。
===>向下(當前AlphaNode子節點表明的規則的全部條件模式)匹配,若是全部的子節點alphaNode中隱藏的條件都符合, 則徹底匹配一條規則,造成議程加入衝突集合,待匹配完全部的規則,再根據規則的優先級執行匹配上的規則的結果部分,更改Fact的數據。
===>向右(進行另外一個規則的匹配),若是全部的子節點alphaNode中隱藏的條件都符合,則徹底匹配一條規則,造成議程加入衝突集合,待匹配完全部的規則,再根據規則的優先級執行匹配上的規則的結果部分,更改Fact的數據。
PS:本文由讀者供稿,有必定的專業性和應用場景,若有疑問可經過聯繫做者後進羣討論!
—————END—————
識別圖片二維碼,關注「無敵碼農」獲取精彩內容
本文分享自微信公衆號 - 無敵碼農(jiangqiaodege)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。