Skip to end of metadata
Go to start of metadata

URule2技术交流QQ群及在线体验示例

在线体验示例:http://58.246.62.194:16808/urule-sample/ 为了不同用户操作互不影响,需要注册账号登录体验操作。

URule2技术交流QQ群:423339793

URule2规则引擎产品教学视频:http://pan.baidu.com/s/1c2xVB24,密码:9xgo

       决策集应该是使用频率最高的一种规则实现方式,在URule决策集中可以有若干个普通规则或循环规则。所谓的普通规则是指一种由如果、那么、否则三个部分构成的规则;而循环规则顾名思义就是可循环的规则,它允许指定一个集合类型的对象,对这个集合中每个对象进行循环迭代,在循环体中则是还是一个由如果、那么、否则构成的普通规则。

       为了方便使用,URule中的决策集有两种类型,分别是向导式决策集和脚本式决策集。所谓向导式决策集,就是通过URule提供的设计器,一步一步通过鼠标点击就可以完成其中的普通规则与循环规则的配置,配合高度可视化的向导式规则设计器,可以最大限度将业务规则可视化,降低规则配置的复杂度;而脚本式决策集顾名思义就是通过在决策集文件当中按URule的脚本语法书写脚本来实现普通规则与循环规则的定义工作。

       向导式决策集因为是图形化,向导方式构建规则,所以适合业务人员使用;而脚本式决策集通过书写脚本构成规则,与传统代码编写类似,所以适合技术人员来编写规则;从功能上看,向导式决策集和脚本式决策集能实现的功能是完全相同的,也就是说向导式决策集中能实现的功能在脚本式决策集也完全可以实现,反之亦然。

向导式决策集

       打开项目,在“决策集”节点右键创建一个向导式决策集文件,创建好的文件通过URule向导式决策集设计器打开后的效果如下:

       在向导式决策集的设计器中,通过顶部的工具栏,点击“添加规则”按钮可以添加一个普通的由如果、那么、否则构成的普通规则;点击“添加循环规则”按钮可以添加一个可以循环的规则。之前介绍的变量、常量、参数、动作四种类型的库文件,在向导式规则里就可以导入使用了。

库文件使用

实际上在决策集、决策表、决策树、评分卡、决策流中都可以使用这四种类型的库文件,它们的定义也都是架构在这四种类型库文件内容的基础之上的。

普通规则

       点击“添加规则”按钮就在下面的工作区里添加了一个普通的规则,如下图所示:


       一个普通规则主体是由如果、那么、否则构成,点击规则名可以对规则名进行修改,修改完成后鼠标点击页签处离开焦点就完成了规则名的修改确认;点击“添加属性”链接可以为当前规则定义相关属性。无论是普通规则还是循环规则都支持下面这些属性

中文属性名英文属性名值类型默认值描述
优先级salienceint0当有多个规则满足条件时,这个值用来决定这些满足条件规则中动作的执行顺序,值越大,执行顺序越靠前,如不设置这个值,那按条件满足的顺序执行。
生效日期effective-dateStringnull当规则设置了生效日期,表示这个规则只有在当前系统日期为大于等于生效日期时才会生效,否则即使条件满足也不会触发当前规则,如不设置,则不会对规则执行产生影响。
失效日期expires-dateStringnull与生效日期对应,当规则设置失效日期时,一旦当前系统日期大于或等于失效日期,即使条件满足规则也不会触发执行,如不设置,则不会对规则执行产生影响。
是否启用enabledbooleantrue当前规则是否启用,如设置为false,即使条件满足规则也不会触发执行,如不设置,则不会对规则执行产生影响。
互斥组activation-groupStringnull系统会自动将此属性相同的规则划为一组,且这个组中只有一个规则会执行,会执行的规则如设置了优先级,则优先级最高的规则执行,否则随机。
执行组agenda-groupStringnull系统会自动将此属性相同的规则划为一组,引擎在执行这些有执行组属性的规则时,需要某个组得到了焦点,或者当前组中要执行的规则设置了auto-focus=true,否则该组下所有规则不会被执行。
自动获取焦点auto-focusbooleanfalse用于设置在有执行组属性时,规则是否会自动执行。
允许循环触发loopbooleanfalse当执行“更新工作区对象”动作时,某些规则可以会再次满足条件,这时这个属性就是用来决定这种类型的规则是否允许再次触发执行。

       规则名及属性定义完成后,接下来就可以开始配置规则的主体部分,首先是“如果”部分,在如果部分当中可以添加若干条件,添加完条件后,就可以通过鼠标点击以向导方式设置条件,如下图:


       对于一个具体的条件来说,我们可以将其分为三个部分,分别是条件左边部分、比较操作符以及条件右边部分。条件左边部分,如上图所示我们可选择的有变量、参数或者方法或函数,当然这相应的需要我们导入相关的变量库、参数库以及方法库;对于操作符目前URule当中提供了下面这些操作比较符,如下图所示:

       这些操作比较符基本已涵盖我们业务当中所有类型的比较操作。选择完比较操作符后,我们就可以来设置条件右边部分。

       条件右边部分相比左边,可选择的值类型会更多一些,如下图:

       一旦选择某种类型值之后,我们就可以进入下一步操作,同时在URule当中无论条件左值还是条件右值都可以进行无限多级简单的加、减、乘、除运算操作,同时与条件左值不同的是,条件右值部分可以添加括号来实现算术运行的优先级定义,如下图所示:

       在配置条件时,需要我们把之前定义好的变量库文件、参数库文件、常量库文件、动作库文件导入进来。对于条件来说,可以是多个条件,也可以是多个复合条件组合,这样都是通过鼠标点击操作完成,这里就不再赘述。

       条件配置完成后,可以为“那么”或“否则”部分添加动作,那么部分的动作只有条件满足时执行,反之,否则部分的动作只在条件不满足时执行,不加动作意味着什么也不干,动作可以有多个,多个动作添加完成后可以通过拖曳改变顺序。目前在URule当中支持的动作类型有三种,分别是:打印内容到控制台、变量赋值以及执行方法或方法,如下图所示:

       所谓的”打印内容到控制台“其实就是将我们需要的信息打印输出到java 控制台,对于内容可以是一个普通的输入值,也可以是一些复杂的值类型或它们的加、减、乘、除组合,及添加括号定义算术运行优先级;变量赋值也就是给当前导入的变量库或参数库的值进行赋值,值类型可以是一个普通的输入值,也可以是一些复杂的值类型或它们的加、减、乘、除组合,及添加括号定义算术运行优先级;最后一种类型的动作是执行方法或函数,要选择执行的方法或函数,前提是我们必须方法所在的动作库文件导入到当前规则文件当中,否则就看不到要执行的方法,一旦选择执行方法后,如果当前方法当中包含参数,那么我们也需要选择相应的值为参数赋值,同样参数的值可以是一个普通的输入值,也可以是一些复杂的值类型或它们的加、减、乘、除组合。动作的具体配置都是基于鼠标点击操作的,比较简单,这里不再赘述。

关于顺序

在向导式规则编辑器中,可以通过鼠标拖曳来改变那么或否则部分的动作顺序,同时,对于多个规则文件,也可以通过拖曳来改变它们的显示顺序。

示例

       下面是一个包含两个普通规则的决策集文件,导入了我们之前配置的那个包含Customer的变量库文件,在第一个规则当中条件满足时执行两个动作,不满足执行一个动作;第二个规则条件满足的话执行两个动作,不满足什么也不做,如下图所示:

      可以看到这两个规则条件都比较简单,并且他们是互斥的,同一时刻最多只会满足一个规则。接下来需要对这个决策集进行测试,测试方法比较简单,点击项目的“知识包”节点,在打开的编辑器中添加一个知识包,并将这个做好的规则集文件放到这个包中,如下图所示:

       知识包是URule中提供的一种用于将一个或多个决策集、决策表、决策树、评分卡、决策流文件打包的工具,知识包的编码属性比较重要,是这个包在当前项目中的ID。定义好知识包及这个包中包含的资源文件后,可以点击工具栏上的“仿真测试”按钮对当前知识包进行仿真测试。

仿真测试

仿真测试是URule当中提供的一种针对知识包的测试工具,通过它可对定义好的知识包预先进行测试,仿真测试中,会将这个知识包中涉及到的所有BOM对象罗列出来,用户可以对BOM对象的属性进行赋值测试。

       点击工具栏上的“仿真测试”按钮可以看到如下图所示的界面:

       因为我们当前知识包中只有一个决策集文件,而这个文件中只导入了我们之前定义的那个包含Customer实体对象的变量库文件,所以在上面的仿真测试页面中我们看到只有一个名为“会员”的BOM对象,在右边表格中罗列了会员的所有属性,我们可以在“值”列中对这些属性进行赋值,然后点击工具栏上的“测试决策包”就可以将当前BOM的值提交到引擎中进行测试,如下图所示。

       上图中我们设置“年龄”属性为20,“是否有房”属性为true,“等级”属性为3,这样就满足第一个规则,所以在点击“测试决策包”按钮后,BOM的“名称”属性会被命名为“金牌会员”,控制台也会有相应输出,这里还有其它的一些情况,可以分别输入不同的值进行测试,这里就不再赘述。

       在仿真测试窗口的工具栏中,“测试决策流”主要是针对决策流进行测试,如果我们的知识包中包含决策流,要对其进行测试,那么就点这个按钮实现;“查看Rete树”按钮是用来通过图形化展示当前知识包所对应的Rete树结构,如上面的示例,点示此按钮看到的Rete树效果如下:

       上图中,就把URule中采用Rete算法构建的树以图形化形式展示出来,如果了解Rete算法,那么可以对比我们定义的决策集看看生成的树结构是否符合要求。实际上,URule在执行知识包时执行的是对应的通过Rete算法构建的树,而非某个具体的规则,理论上来说,所以它可以最大程度保证在执行条件匹配时的性能。

循环规则

       在决策集设计器中,点击工具栏上的“添加循环规则”按钮就可以添加一个循环规则,如下图所示:

       可以看到,循环规则的名称与属性与普通规则一样;接下来是“循环对象”属性,要求我们指定一个集合类型的对象,这样规则在运行时将会对这里选择的集合进行迭代;下面是“开始前动作”属性,顾名思义,就是在循环规则执行前做的一些动作,通常我们会在这个地方做一些初始化的动作,比如临时参数的初始化赋值等,同样这里的动作可以是0~n个,如果不定义那么就不执行;接下来是一个普通规则的规则体,也就是如果、那么、否则部分,定义方式与普通规则完全相同,这样在循环规则执行时,每迭代一次“循环对象”就会将当前迭代的对象插入到工作区,尝试匹配一次这里的规则体,如果满足条件就执行;最后是“结束后动作”部分,它在循环执行完成后执行,动作可以是0~n个,不定义就不执行。

示例

       举例说明循环规则的用法,首先我们需要在Customer实体类里添加一个新的属性orders,如下代码所示:

添加orders属性

//......

@Label("订单")
private List<Order> orders;

//......

       Order类源码如下:

Order类源码

       打开我们的customer变量库文件,在"会员"分类下添加orders变量,添加新的订单分类,如下图:

       这样,“会员”与“订单”之间就形成了一个一对多的关系。接下来我们需要利用循环规则实现一个简单的小需求,那就是统计当前会员的符合条件的订单价格的总额,我们目前定义的两个BOM对象中,没有哪个属性可用于存储订单价格总额,所以需要添加一个临时的参数值,用来存储订单总额的值。

       创建一个参数库文件,在其中添加一个名为amount的参数值,如下图所示:

提示

注意,这个名为total的参数我们实际上应该将它的数据类型设置为Integer,但这里却设置成了String,这样在后面做累加的时候就需要注意一下,后面会提到。

       这些库文件准备好了之后,接下来我们就可以来定义一个循环规则来实现统计总价的需求了,定义好的规则如下:

       从上图中可以看到,我们这里的循环规则的循环对象是“会员”的“订单”,条件是订单价格要大于10,同时数量要大于0,如果这两个条件满足,那么就对参数总价进行赋值(参数库需要导入),循环结束后我们在控制台输入一段描述。在这个循环规则当中,我们还添加了一个“开始前动作”,这个动作就是对参数的总价进行赋值为0,其实就是对其进行初始化,之所以这么做是因为在参数库中我们定义总价时的数据类型为String,String的默认值是null,无法进行数据转换再累加,所以必须要对其进行初始化赋值。如果参数库中总价数据类型为Integer,那么这里的初始化赋值操作就可以省去了。

       点击“知识包”节点,添加一个用于测试当前这个包含循环规则的决策集文件,如下图所示:

       点击工具栏“仿真测试”按钮,对当前循环规则包进行测试,在仿真测试窗口中,我们双击会员的订单属性输入框,在弹出的窗口中选择类型为“订单”,如下图所示:

       确认后,会弹出“订单”对象的列表,我们可以添加几条,这样就实现了为“会员”这个对象添加若干个订单子对象的功能,如下图所示:

       确认后,可以看到会员的订单属性值是一个JSON字符串,这个JSON串表示的就是具体的订单列表值。再给会员的“名称”属赋个值,然后点击“测试决策包”,就完成了订单总计统计功能,切换到“参数”,可以看到“总价”的值已经计算出来,如下图所示:

       可以看到订单中“大米”因价格未满足条件,而未被计入总价。

       在循环规则当中,有些时候我们可能需要从子对象中找出一个符合条件的就可以了,这样后面的就不需要循环了,针对这种情况,URule里还提供了一个名为“跳出循环”的方法,我们只需要在循环规则体的那么中添加这个方法即可,如下图所示:

       保存,再次进行仿真测试,我们发现总价的值就只有第一个订单的价格。

可引用的条件

       在URule2的普通规则或循环规则当中,在“如果”部分添加条件时,可以添加一种叫“命名联合条件”项目,如下图所示:

       点击这个菜单项,就可以添加一个可以进行命名引用的条件项目,如下图所示,这个项目有两部分构成:第一部分是引用的名称,需要我们手工输入一个字符串作为引用名;第二部分就是具体要引用的变量对象,这里的引用只能针对变量进行引用,比如这里选择“会员”,引用名为“c”,那么就表示"c"这个对象表示的是满足当前条件的"会员"变量对象:

       接下来,就可以在这个引用变量下添加具体的子条件,在这些子条件当中,条件的左边部分只能选择引用目标变量的属性,右边部分与普通条件的右边部分相同,如下图所示:

       添加完可命名的引用条件后,在规则的“那么”部分就可以使用这个变量名,需要注意的是引用变量只能在条件的“那么”部分使用,因为只有满足条件,引用的变量才会被存储,才有意义。大多数情况下,我们的规则都不需要可命名的引用变量,只在某些特殊情况下才需要采用这种用法。下面来举例说明这种用法。

       在这个例子当中,我们有若干个Customer对象实例,这些Customer实例中有一个Customer实例“等级”属性大于10,“婚否”属性值为false,同时还有一个Customer实例,同时Customer实例“等级”属性等于0,“年龄”属性小于18。在我们的规则中需要从这批Customer对象实例中找到这两个Customer实现,然后在控制台打印出这两个对象的“名称”属性,然后再将他们的“年龄”属性相加输出到控制台。

关于例子

上面的规则看似荒诞,但在实际业务中其它场景下会有类似需求,这里就简单用现有的变量来模拟这种需求。

       我们创建好的规则如下图所示:


       在上面的规则当中,c这个引用名对应的是“等级属性大于10,婚否属性值为false的Customer实例”;c1对应的是“等级属性等于0,年龄属性小于18Customer实例”,如果条件满足,在规则的“那么”部分,我们执行两个输出内容到控制台的动作,也就是输出c和c1两个变量的名称属性值。

       在这个例子当中,我们需要有多个Customer实例,所以无法使用URule中提供的仿真测试功能来模拟,这里我们将通过代码来模拟多个Customer的情况。

       首先在“知识包”节点创建一个新的知识包,在这个包中将这个规则添加到包中,如下图所示:

       编写测试代码,代码内容如下所示:

测试类源码

       在上面的代码当中,可以看到,只有c1和c2两个Customer实例满足我们的规则要求,所以运行时应该只会输出c1和c2两个对象信息。

规则引擎代码调用

在上面的代码当中,涉及到URule规则引擎代码调用,这个在后面有专门的章节进行详细介绍,这里不再赘述。

       接下来,我们创建一个JSP,在这个JSP中调用这里的InvokeTest类的test方法,实现规则调用,JSP源码如下:

JSP源码

       运行应用,浏览这个JSP,可以在控制台看如下图所示输出:

       在上面的例子中,我们假定所有的Customer实例中只有两个满足条件,假如这些实例中有两个以上满足条件会出现什么情况呢?比如有三个Customer实例满足规则设定的条件,在这个时候URule规则引擎会按插入到KnowledgeSession顺序,取到最先满足条件的两个Customer实例,然后对其进行计算,后面如果还有满足条件的Customer实例,就不再处理;如下面的代码,我们将c4这个Customer的实例进行修改,使其也满足规则:

修改C4对象条件

       再次运行我们的JSP,可以看到与之前结果完全相同,URule规则引擎没有理会c4这个实例,尽管它也满足条件。如果我们希望引擎可以处理所有满足条件的Customer的话,那我们需要在规则中添加一个名为“允许循环触发”的属性,将属性值设置为“是”,这样,对于有两个以上满足条件的Customer对象实现,URuleURule规则引擎会对所有满足条件的Customer实现进行一个排列组合,以循环触发规则。添加了属性后的规则如下图所示:

       保存规则,打开“知识包”管理页面,选中“ref-test”这个知识包,点击工具栏上的“发布当前知识包”按钮,对修改后的规则进行发布,再次运行我们的JSP,可以看到控制台输出如下图所示内容:

       如控制台看到的内容所示,在允许循环触发的情况下,URule将满足条件的三个Customer对象进行排列组合,分两次触发规则。

Labels
  • No labels