您的位置:首页 > 其它

疯狂Activiti6.0连载(17) Drools规则语法概述

2017-11-22 21:08 507 查看
 本文节选自《疯狂工作流讲义(第2版)》
京东购买地址:https://item.jd.com/12246565.html

工作流Activiti6电子书:http://blog.csdn.net/boxiong86/article/details/78488562
工作流Activiti6教学视频:http://blog.csdn.net/boxiong86/article/details/78608585


Drools规则语法概述

Drools有一套自己的规则语言,通过该规则语言,可以将不同业务领域的业务“语言”转换为可以被Drools解读的规则。与其他的编程语言一样,规则语言拥有自己的语法,例如语言中的关键字、变量定义、函数定义和函数调用等。本小节将对Drools的规则语法作初步的讲解。


规则文件结构

每种语言都会有自己的语言结构,例如Java语言使用class来定义一个类、使用package来声明包等,同样地,规则语言同样有自己的结构,一份规则文件的内容主要包括以下部分:

     package:声明该规则文件的包名,相当于为规则文件提供一个命名空间,该名称可以不与规则文件所在的目录相关联,例如“package
org.crazyit.drools.sale;”,package必须要在规则文件的最前面,否则在编译规则文件时,将会抛出错误信息,信息内容为:mismatched
input 'package' expecting one of the following tokens: '[package, import, global, declare, function, rule, query]。

     import:该关键字就好像Java中的import一样,声明规则在编译和运行时所使用到的Java类,如14.2.3的例子中,规则文件需要使用Person对象,那么就需要使用import关键字导入该对象,但是14.2.3例子中并没有显式导入Person对象,这是由于使用了package定义了“org.crazyit.drools”命名空间,而Person类的包恰好是“org.crazyit.drools”,与package相同的包名,因此不需要显式进行导入。除了会将package声明的Java包下全部的类导入外,默认还会导入java.lang包下全部的类。

     global:用于定义全局的变量,这些变量可以是具体的数据或者服务对象,规则文件中的全部规则均可以使用global定义的变量,例如“global
java.util.List.myList”。全局变量更多会用于存放规则结果或者与应用进行数据交互。

     function:用于在规则文件中定义逻辑语句,使用方法的定义可以将部署逻辑独立存放到规则文件中,这些方法可以供多个规则调用,就像Java类中的工具(private)方法。

     query:使用查询可以到工作存储空间中查找符合条件的事实数据,事实数据均会被存放到工作存储空间中,query是其中一种查询这些事实数据的途径。

     rule:一个rule定义一个业务规则,当符合某个特定条件时,就执行相应的行为,条件被称为LHS(Left
Hand Side),行为被称为RHS(Right Hand Side),使用when
LHS then RHS的语法规则定义一个rule。
注:在规则文件中,除了package必须要定义在规则文件最前面外,其他的组成部分均可以不按顺序定义,但建议按照以上描述的顺序进行定义,以便加强规则文件的可读性。

 


关键字

规则语言中有两类的关键字:硬(hard)和软(soft)关键字,硬件关键字是指约束性较强的一类关键字,即规则文件中不允许使用硬关键字进行命名,包括对象名称、属性名、方法名等规则文件中的元素,硬关键字有true、false和null三个。

跟硬关键字相比,软关键字的限制就相对宽松,在进行规则元素命名时,可以使用这些关键字,但是为了避免冲突,建议尽量不要使用关键字进行命名,在Drools的官方文档中,共展示了几十个软关键字:lock-on-active、date-effective、date-expires、no-loop、auto-focus、activation-group、agenda-group、ruleflow-group、entry-point、duration、package、import、dialect、salience、enabled、attributes、rule、extend、when、then、template、query、declare、function、global、eval、not、in、or、and、exists、forall、accumulate、collect、from、action、reverse、result、end、over、init,这些关键字在各自的语义中均有不同的作用,例如lock-on-active、date-effective等用来定义规则属性的关键字,例如function、rule等用来定义规则元素的关键字,除此之外,还包括定义运算的关键字、定义对象和行为的关键字等。这部分的关键字的使用会在后面章节中涉及。


规则编译

在向KnowledgeBuilder添加规则资源时,KnowledgeBuilder会将解析到的规则内容进行编译,在编译过程如果遇到语法的错误,将会这些错误封装为一个KnowledgeBuilderResult的集合,存放在PackageBuilder的实例中,如果想获取这些编译的错误信息,可以调用KnowledgeBuilder的getErrors方法,该方法返回一个PackageBuilderErrors实例,调用toString方法即可查看编译的全部错误信息。例如往规则文件中随便加入不规范的语句,如代码清单14-3所示。

代码清单14-3:codes\14\14.3\grammar\resource\grammar.drl

package org.crazyit.drools;

abc

rule "Test Rule"

    when

        Person(name == "Crazyit");

    then

        System.out.println("Welcome to Drools");

end

代码清单14-3中的“abc”,不是规则语法的关键字,明显违反了语法规则,KnowledgeBuilder在加载该规则文件资源和编译时,调用KnowledgeBuilder的getErrors方法可以得到异常信息,如以下代码所示:

//创建一个KnowledgeBuilder

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory

.newKnowledgeBuilder();

//添加规则资源到KnowledgeBuilder

kbuilder.add(ResourceFactory.newClassPathResource("grammar.drl",

TestError.class),
ResourceType.DRL);

//输出错误信息

if (kbuilder.hasErrors()) {

System.out.println(kbuilder.getErrors().toString());

System.exit(0);

}

对代码清单14-3的规则文件进行编译,输出结果如下:

[2,0]: [ERR 107] Line 2:0 mismatched input 'abc' expecting one of the following tokens: '[package, unit, import, global, declare, function, rule, query]'.

[0,0]: Parser returned a null Package

根据以上的错误信息可知,该编译错误的代号为“ERR 107”,出现在规则文件的第二行,错误信息大致为“abc是不匹配的语言符号”,关于错误代号,在编译时出现的错误代号值从101到108,分别代表不同的错误类型,笔者建议对这些错误代号不需要太关心,遇到编译问题时,仔细阅读输出的错误信息即可发现问题所在。

京东购买地址:https://item.jd.com/12246565.html
 
 本文节选自《疯狂Workflow讲义(第2版)》
工作流Activiti6电子书:http://blog.csdn.net/boxiong86/article/details/78488562
工作流Activiti6教学视频:http://blog.csdn.net/boxiong86/article/details/78608585
本书代码共享地址:https://gitee.com/yangenxiong/CrazyActiviti



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: