Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则,从而便于学习和理解。并且,还可以将 Java 代码直接嵌入到规则文件中,这令 Drools 的学习更加吸引人。

Drools 还具有其他优点:
  • 非常活跃的社区支持
  • 易用
  • 快速的执行速度
  • 在 Java 开发人员中流行
  • 与 Java Rule Engine API(JSR 94)兼容
Drools 是业务逻辑集成平台,被分为4个项目:
  • Drools Guvnor (BRMS/BPMS):业务规则管理系统
  • Drools Expert (rule engine):规则引擎,drools的核心部分
  • Drools Flow (process/workflow):工作流引擎
  • Drools Fusion (cep/temporal reasoning):事件处理

官网:http://www.drools.org/#

官方文档:http://www.drools.org/learn/documentation.html

Drools语法

规则文件

规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件

规则文件

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分

如:
package com.sankuai.meituan.waimai.drools.demo

import:导入规则文件需要使用到的外部规则文件或者变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法

import com.drools.demo.point.PointDomain;

rule:定义一个具体规则。rule "ruleName"。一个规则可以包含三个部分:

  • 属性部分: 定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。

  • 条件部分(LHS): 定义当前规则的条件,如 when Message(); 判断当前workingMemory中是否存在Message对象。

  • 结果部分(RHS): 即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。这里可以写普通java代码

rule部分
rule "ruleName"
no-loop true
 <span class="hljs-keyword">when</span>
$message<span class="hljs-symbol">:Message</span>(status == <span class="hljs-number">0</span>) <span class="hljs-keyword">then</span>
System.out.println(<span class="hljs-string">"fit"</span>);
$message.setStatus(<span class="hljs-number">1</span>);
update($message);

end

规则详情
属性详情
  • no-loop: 定义当前的规则是否不允许多次循环执行,默认是false;当前的规则只要满足条件,可以无限次执行。什么情况下会出现一条规则执行过一次又被多次重复执行呢?drools提供了一些api,可以对当前传入workingMemory中的Fact对象进行修改或者个数的增减,比如上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操作会触发规则的重新匹配执行,可以理解为Fact对象更新了,所以规则需要重新匹配一遍,那么疑问是之前规则执行过并且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update之后,之前的修改都会生效。当然对Fact对象数据的修改并不是一定需要调用update才可以生效,简单的使用set方法设置就可以完成,这里类似于java的引用调用,所以何时使用update是一个需要仔细考虑的问题,一旦不慎,极有可能会造成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,如果本身的RHS部分有update等触发规则重新执行的操作,也不要再次执行当前规则。

    但是其他的规则会被重新执行,岂不是也会有可能造成多次重复执行,数据紊乱甚至死循环?答案是使用其他的标签限制,也是可以控制的:lock-on-active true

  • lock-on-active:lock-on-active true 通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版

  • date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”

  • date-effective:设置规则的生效时间,时间格式同上。

  • duration:规则定时,duration 3000,3秒后执行规则

  • salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序。

**rule attributes**
条件部分- LHS
  • when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列

    如:当前规则只有在这三个条件都匹配的时候才会执行RHS部分
when
eval(true)
$customer:Customer()
$message:Message(status==0)
  • eval(true):是一个默认的api,true 无条件执行,类似于 while(true)

  • 操作符>>=<<===!=containsnot containsmemberOfnot memberOfmatchesnot matches

操作符
  • contains: 对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值

    Person( fullName not contains "Jr" )
  • not contains:与contains相反。
  • memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象

    CheeseCounter( cheese memberOf $matureCheeses )
  • not memberOf:与memberOf正好相反
  • matches:正则表达式匹配

    Cheese( type matches "(Buffalo)?\\S*Mozarella" )

    注意: 就像在Java中,写为字符串的正则表达式需要转义“\”
  • not matches:与matches正好相反
结果部分- RHS

当规则条件满足,则进入规则结果部分执行,结果部分可以是纯java代码

  • then:
then
System.out.println("OK"); //会在控制台打印出ok
end
  • insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定
  • update:更新
  • modify:修改,与update语法不同,结果都是更新操作
  • retract:删除
rule "Rule 03"
when
$number : Number( )
not Number( intValue < $number.intValue )
then
System.out.println("Number found with value: " + $number.intValue() );
retract( $number );
end
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 -
Drools方法定义
  • function
function String hello(String name) {
return "Hello "+name+"!";
}
Drools声明类型
  • declare:声明类型
  • 声明Class、Enum etc类型
  • 声明元数据
声明类类型
declare  Address
number : int
streetName : String
city : String
end
声明枚举类型
declare enum DaysOfWeek
SUN("Sunday"),MON("Monday"),TUE("Tuesday"),WED("Wednesday"),THU("Thursday"),FRI("Friday"),SAT("Saturday");
fullName : String
end
声明元数据类型

元数据可以被分配给在Drools中几个不同的结构:

  • fact types
  • fact attributes
  • rules
定义格式:
@metadata_key(metadata_value)
例子:
@author( Bob ) import java.util.Date

declare Person

@author( Bob )

@dateOfCreation( 01-Feb-2009 )

name : String @key @maxLength
( 30 )

dateOfBirth : Date address : Address

end

声明元数据类级别 关键词

  • @role( <fact | event> )
import some.package.StockTick
declare StockTick
@role ( event )
end
  • @typesafe( <boolean> )
  • @timestamp( <attribute name> )
declare VoiceCall
@role( event )
@timestamp( callDateTime )
end
  • @duration( <attribute name> )

  • @expires( <time interval> )

  • @propertyChangeSupport

  • @propertyReactive

声明元数据属性级别 关键词

  • @key

两个方面影响:

  • 根据@key作为类标识符,类比较以 @key 的字段为准
  • 根据@key字段生成构造函数
declare Person
firstName : String @key
lastName : String @key
age : int
end
  • @position
declare Cheese
name : String @position(1)
shop : String @position(2)
price : int @position(0)
end

设计

Drools vs ILog vs Jess vs Mandarax

优点
Drools 开源、社区非常活跃、易使用、免费、JSR94兼容(JSR94是Java Rule Engine API)、支持Java、强大的工具集 只支持一种推理方式、安全性不够
ILog 性能高(电信领域使用)、易使用 商业产品、不开源
Jess 支持2种推理方式(正向链和反向链)、很强的表示、推理能力、支持AOP 不开源、无规则管理工具、不易使用
Mandarax 开源、免费、支持Java JSR94不兼容(JSR94是Java Rule Engine API)、已经不更新、社区不活跃、并且文档不全
推理方式
  • 正向链推理:一条由问题开始搜索,并得到其解答的链称为正向链推理。
  • 反向链推理:一条由假设回推到支持该假设的事实的链称为反向链推理。

作者 @九都散人

2016 年 5月 6日


参考:

Jess 反向链推理机理及诊断专家系统开发模式研究

http://www.docin.org/p-86340503.html

Drools 6.4 Final 文档

      </div>

Drools介绍与使用的更多相关文章

  1. 小明历险记:规则引擎drools教程一

    小明是一家互联网公司的软件工程师,他们公司为了吸引新用户经常会搞活动,小明常常为了做活动加班加点很烦躁,这不今天呀又来了一个活动需求,我们大家一起帮他看看. 小明的烦恼 活动规则是根据用户购买订单的金 ...

  2. 规则引擎drools封装

    一.前言 网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践 ...

  3. Drools 规则引擎应用

    规则引擎-drools 1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 .... ...

  4. Drools 规则引擎应用 看这一篇就够了

    1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ...... 1.2传统做法 1 ...

  5. Drools Expression 介绍

    用好Drools 中的表达式是你的规则引擎能否强大的必要条件 http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_sin ...

  6. drools语法介绍

    这里没有翻译http://docs.jboss.org/drools/release/6.4.0.Final/drools-docs/html_single/index.html上的内容 而是参考了网 ...

  7. Drools 规则学习

    Drools 规则学习 在 Drools 当中,一个标准的规则文件就是一个以“.drl”结尾的文本文件,由于它是一个标准的文本文件,所以可以通过一些记事本工具对其进行打开.查看和编辑.规则是放在规则文 ...

  8. Drools规则

    1.实现业务逻辑和业务规则的分离,实现业务规则的集中管理 2.可以动态的改变业务规则,从而快速响应需求变更 3.业务分析人员也可以参与编辑.维护系统的业务规则 fact:一个普通的JavaBean插入 ...

  9. 使用规则引擎Drools计算圆周率PI

    实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能. 使用了策略模式实现. <规则引擎与RETE算法介绍> PPT : http://files.cnblogs.com/lov ...

随机推荐

  1. C#---数据库访问通用类、Access数据库操作类、mysql类 .

    //C# 数据库访问通用类 (ADO.NET)using System;using System.Collections.Generic;using System.Text;using System. ...

  2. JavaScript 正则表达式(转自 mozilla)

    正则表达式是被用来匹配字符串中的字符组合的模式.在JavaScript中,正则表达式也是对象. 这种模式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match.r ...

  3. ORACLE_AQ 队列

    Oracle AQ Demo,Step by Step 我准备用AQ来做一个数据仓库系统,提交分析任务队列.有以下需求: 1.利用通知异步的执行存储过程 2.设定队列大小极限 3.出列即删除 OK,l ...

  4. TCP/IP与Http与socket的关系

    1 理清概念: TCP/IP是一个大的协议族(只不过TCP和IP是super star所以就这么命名了),它包括了: 应用层协议:FTP.HTTP.TELNET.SMTP.DNS(协议): 传输层协议 ...

  5. 【转】HIVE UDF UDAF UDTF 区别 使用

    原博文出自于:http://blog.csdn.net/longzilong216/article/details/23921235(暂时) 感谢! 自己写代码时候的利用到的模板   UDF步骤: 1 ...

  6. [转]iOS WebKit browsers and auto-zooming form controls

    问题描述:https://github.com/jquery/jquery-mobile/issues/2581 本文转自:http://www.456bereastreet.com/archive/ ...

  7. Spring.Net学习笔记(二)-数据访问器

    Spring对ADO.NET也提供了支持,依赖与程序集Spring.Data.dll IDbProvider IDbProvider定义了数据访问提供器的基础,配置如下 <?xml versio ...

  8. Java提要

    一.四种权限修饰符 1.访问控制修饰符 作用: 用于控制被修饰变量.方法.类的可见范围. public 的访问级别是最高的,其次是 protected.默认和 private. 成员变量和成员方法可以 ...

  9. HDU_1421_搬寝室_dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1421 搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Me ...

  10. CAD使用GetxDataLong读数据(网页版)

    主要用到函数说明: MxDrawEntity::GetxDataLong2 读取一个Long扩展数据,详细说明如下: 参数 说明 [in] LONG lItem 该值所在位置 [out, retval ...