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源创计划”,欢迎正在阅读的你也加入,一块儿分享。