5.脚本式规则集
概述
在向导式规则集中,我们通过鼠标点击就可以定义出各种类型的复杂业务规则;如果你是一个程序员,可能会更青睐代码的方式来定义业务规则,所以在URule Pro中还提供了脚本式规则集,让我们可以采用脚本的方式来定义业务规则。与向导式规则集对应,脚本式规则集里可以实现向导式规则中能实现的所有功能,反过来也是一样。
虽然说脚本式规则集能实现向导式规则集的所有功能,但在实际使用中,我们还是推荐大家使用向导式规则集来定义我们的业务规则,这是因为向导式规则集是通过鼠标点击方式,一步步引导我们进行操作,所以它的出错机率很小,所以推荐使用。在URule Pro当中所有的功能点都可以采用向导方式来完成定义。
在脚本式规则集中,采用URule Pro自定义的一套脚本语法,关键字既可以使用英文也可以是中文,在一个普通规则或一个循环规则当中,我们可以使用纯英文关键字来定义,也可以全部使用纯中文关键字来定义,如果你愿意,也可以使用中英文混合的关键字来定义。因为支持中文关键字,使得URule Pro的脚本式决策集更加适合国人编写,可读性也就更强,再配合URule Pro中提供的脚本式决策集编辑器中提供的全功能代码提示功能,可大幅提高脚本式决策集的编写效率。
打开URule Pro控制台,在项目下的“决策集”节点右键,选择“添加脚本式决策集”菜单项,即可创建一个新的脚本式决策集文件,如下图所示:
语法
URule Pro中的脚本的语法定义与解析采用的是ANTLR实现,在一个脚本式决策集当中,同样可以导入变量库、常量库、参数库以及动作库,同样可以编写普通规则和循环规则。对于一个完整的脚本规则文件,它的内容主要由三部分构成,分别是:导入资源库的头部分、规则定义部分以及函数定义部分;我们先来看看资源库导入的头部分。
库文件导入部分
所谓的库文件导入部分,就是指在整个脚本规则文件的最顶部来定义导入哪些库文件,前面提到,通过最上方的工具栏,可以将我们规则当中需要用到的资源为导入进来。以导入变量库文件为例,在导入操作之前,需要我们首先将编辑光标定位于文件头部,然后点击最上方工具栏中“导入常量库”按钮,在弹出窗口中选择目标资源库文件,确定后,就可以在当前脚本规则文件中加入要导入的资源库文件,如下图所示:
导入其它类型的资源库操作也是一样,每条导入可以添加“;”结尾,也可以不加;在导入资源库文件时,如果我们选择当前资源库文件的某个具体版本,那么版本号就会出现在文件名的后方,如下图所示:
可以看到版本号置于文件结尾处,与文件名之间以“:”分隔。
需要注意的是,导入库文件的定义信息,必须要置于整个脚本规则文件的顶部,具体的规则及函数定义必须位于导入资源库定义信息之下,否则就有语法错误。但对于变量库、参数库、常量库及动作库之间的顺序则是任意的。
接下来我们来看看规则定义,规则的位置是任意的,只是保证它们的位置在导入资源库定义内容之下就行。
规则定义
在一个脚本式规则文件当中,可以添加零至多个普通规则或循环规则定义信息,其定义位置必须要在导入库文件的定义信息之下。一个标准的普通规则定义的结构如下。
在一个普通规则当中,else部分如果没有动作可定义,那么是可以省略不写的,就像下面这样:
看完普通规则后,我们再来看看循环规则定义,下面是一个标准的循环规则定义结构:
对照向导式决策集里的循环规则定义,可以看到结构完全一致,唯一不同的是这里采用脚本方式实现。同样在脚本式循环规则的循环体中,如果没有“否则”部分,那么这里的“else”部分的定义就可以省略,这与普通规则一样。
规则属性
无论是普通规则,还是循环规则,属性定义部分都是一样的,而且与向导式规则中普通规则和循环规则保持一致。
如果不记得属性有哪些可以通过ALT+"/"键打开代码提示,选择需要的属性即可,多个属性之间可以用空格或","号分隔,具体属性中英文名及描述见规则属性部分介绍,如下图所示:
在脚本式决策集编辑器当中,通过使用ALT+"/"键就可以打开当前光标所在位置的代码提示功能,如果你在按ALT+"/"键时没出现代码提示菜单,则你的浏览器可能已占用了这个快捷键,我们必须要将这个快捷键开放出现,留给脚本式决策集编辑器使用。
属性赋值通过”=“实现,多个属性之间需要添加空格或回车,对于String类型的属性值需要添加双引号包裹,日期类型要采用“yyyy-MM-dd HH:mm:ss”格式来定义,布尔类型则直接输入true或false,如下图所示的属性:
条件定义部分
对于一个普通规则,条件定义部分在if与then之间,对于循环规则,条件定义部分指的是循环体中在if与then之间的部分。
在条件定义部分中我们可以添加具体的业务条件判断,与向导式规则类似,在编写脚本式规则条件时,单个条件也是由条件左边部分,比较操作符及条件右边部分。在条件左边部分,同样可以使用参数、变量及方法,当然也可以添加简单的加、减、乘、除,对于条件的比较操作符,我们可以通过ALT+"/"键打开代码提示来进行查看,如下图所示:
条件左边值
条件左边值格式为:变量/参数/方法 [+][/][*][/] 变量/参数/方法/数字/字符串 [+][/][*][/]变量/参数/方法/ 数字/字符串...
合法的条件左边值定义示例 |
---|
员工.salary/10 |
员工.salary-10 |
员工.salary+10-5*2/3 |
员工.salary+10 |
员工.salary*10 |
员工.salary |
参数.approve |
参数.amount+10 |
MethodTest.判断用户名("张三")+12*12 |
MethodTest.判断用户名("张三") |
条件右边值
与条件左边值类似,条件右边值除了可输入单个普通的数字、字符串、变量、参数、方法、常量外,也可以使用一级或多级加、减、乘、除操作连接复杂表达式,但一级或多级加、减、乘、除操作的右边对象同样可以是普通的数字、字符串、变量、参数、方法、常量,其语法格式如下:
数字/字符串/变量/参数/方法/常量 [+][-][*][/] 数字/字符串/变量/参数/方法/常量 [+][-][*][/] 数字/字符串/变量/参数/方法/常量 ...
在条件右边值当中,可以使用括号来实现加、减、乘、除运算优先级,依照条件右边值语法格式,上面条件左边值格式为不合法的示例,在条件右边值中都是合法的。在条件左值当中,我们可不以使用常量,但在条件右值当中就可以使用常量,下面是几个合法的条件右边值定义示例:
合法的条件右边值定义示例 |
---|
员工.salary+10-(员工.level-2.11*(2+2.1)) |
MethodTest.判断用户名("张三")+员工.salary |
员工.salary+员工.level+10 |
MethodTest.判断用户名("张三")+12*12 |
员工.salary+10-5*2/3*(2+1.11) |
MethodTest.判断用户名("张三") |
员工.salary+10-5*2/3 |
员工.salary-10 |
员工.salary-10 |
参数.approve |
参数.amount+10 |
员工.salary+10 |
员工.salary*10 |
true |
false |
10 |
"yes" |
$学历.大专 |
10+20 |
20*0.08+30 |
多条件组合
在规则编写过程当中,如果有多个条件,那么可以采用“and”或“or”符号来对多个条件进行连接组合,同时对于组合的条件,还可以添加括号来实现组件条件计算的优先级,在未添加括号的多个组合条件之间,要使用相同连接符号,也就是说在未添加括号的多个组合条件之间,要么使用“and”,要么使用“or”。下面当前罗列了一些常用的组合条件示例:
组合条件 | 描述 |
---|---|
员工.level==1 or 员工.level==2 | 两条件只满足一个条件即可 |
员工.salary>1000 and 员工.salary<10000 | 两条件必须同时满足 |
员工.salary>1000 and 员工.salary<10000 and (员工.level==1 or 员工.level==2 or (员工.学历 == $学历.大专 and 员工.salary>员工.level*1.5 and 员工.dept.id=="D21")) | 前两个条件满足,括号内前两个条件与最后那括号内条件必须要满足其一 |
员工.salary>1000 and 员工.salary<10000 and (员工.level==1 or 员工.level==2) | 前两个条件必须同时满足,同时后面两个条件必须要有一个满足 |
员工.学历 == $学历.大专 and 员工.salary>员工.level*1.5 and 员工.dept.id=="D21" | 表示三个条件必须同时满足 |
通过上面的例子可以看到,通过“and”或“or”符号来对多个条件进行连接组合以及添加括号或多层嵌套括号可以实现非常复杂的条件组合,从而满足我们的业务需求。对于连接多个条件的“and”或“or”符号,在使用时还可以用“&&”或“||”来替换,程序员一定很熟悉,“&&”或“||”在代码中表示的就是“并且”“或者”,除此之外,我们还可以直接使用“并且”“或者”的中文来连接多个条件,如下面的截图所示:
在脚本式规则中,条件定义的可读性与向导式规则相比就很差了,所以这也是我们不推荐使用脚本式规则的原因之一。
动作定义部分
脚本式决策集中普通规则的的动作定义部分写在“then”与“end”之间或者是“else”与“end”之间,循环规则中除了循环体中可在上述两个地方添加动作外,还可以在"loopStart"与“if”之间或"loopEnd"与"end"之间添加动作,动作可有一个或多个,每个动作以“;”或回车结束。可执行的动作有三种类型,那就是为变量或参数赋值、执行方法、执行自定义函数以及控制台内容输出。我们首先来看看针对变量或参数的赋值操作。
赋值操作
赋值操作的语法格式如下:
变量或参数 = 数字/字符串/变量/参数/方法/常量 [+][-][*][/] 数字/字符串/变量/参数/方法/常量 [+][-][*][/]数字/字符串/变量/参数/方法/常量 ...
可以看到,针对变量或参数的赋值,首先要写出具体的变量或参数名,然后是“=”符号,接下来在“=”右边是一个简单或复杂的赋值表达式。在这里赋值表达式与条件的右边值格式完全相同,所以这里不再赘述。
执行方法
在做执行方法操作时,我们需要导入定义目标方法的动作库,一旦导入,我们通过ALT+"/"键代码提示中就可以看到当前文件中可用的方法,选择好一个方法后,如果这个方法中包含参数,那么我们还要根据在方法定义时指定的参数类型,为方法填充适当的参数,对于方法参数,它也支持类型条件右边值那种复杂的语法格式,执行方法的语法格式如下:
方法名([参数1,参数2...])
执行自定义函数
所谓执行自定义函数是指执行在当前规则文件当中定义的自定义函数,关于自定义函数见后面内容描述,执行自定义函数的格式如下:
函数名([参数1,参数2...])
控制台内容输出
在URule Pro当中,内置了一个名为out的向控制台内容输出内容的函数,其语法格式如下:
out(数字/字符串/变量/参数/方法/常量 [+][-][*][/] 数字/字符串/变量/参数/方法/常量 [+][-][*][/] 数字/字符串/变量/参数/方法/常量 ... )
从格式中可以看到,它以“out”开头,后面的括号中就是我们需要输出的内容,对于输出内容格式,与条件的右边值格式完全相同。
对中文的支持
在规则编写当中,无论是普通规则还是循环规则,所有的关键字可以使用对应的中文来进行替代,具体见下表:
关键字 | 对应的中文关键字 |
---|---|
rule | 规则 |
loopRule | 循环规则 |
loopTarget | 循环对象 |
loopStart | 开始前动作 |
loopEnd | 结束后动作 |
if | 如果 |
then | 那么 |
end | 结束 |
and | 并且 |
or | 或者 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
EndWith | 结束于 |
NotEndWith | 不结束于 |
StartWith | 开始于 |
NotStartWith | 不开始于 |
In | 不集合中 |
NotIn | 不在集合中 |
Match | 匹配 |
NotMatch | 不匹配 |
EqualsIgnoreCase | 忽略大小写等于 |
NotEqualsIgnoreCase | 忽略大小写不等于 |
下面的截图中是一个用英文关键字编写的普通规则
对应的中文规则如下:
下图中是一个用中英文关键字混合的规则:
在脚本式决策集中,可通过//来添加单行备注,多行备注用/..备注内容../实现
尽管在脚本式规则集中提供了与向导式规则集一样的功能,但由于其需要手写的特点,决定了它的编写过程中出现错误的可能性,同时,脚本式规则中多条件的组合可读性相比向导式规则中图形化展现方式也要差很多,所以我们还是推荐大家使用向导式规则集。在URule Pro中,所有的功能点都可以通过向导配置的方式完成,完全不需要手写任何脚本。