java规则引擎《drools7.0.0.final规则引擎教程》第4章4.4约束(pattern的一部分)

无信不立      2022-04-07     121

关键词:

4.4.3 约束(Pattern的一部分)

前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false的表达式,比如下面的5小于6,就是一个约束条件。

技术分享图片
Person( 5 < 6 )
View Code

从本质上来讲,它是JAVA表达式的一种增强版本(比如属性访问),同时它又有一些小的区别,比如equals方法和==的语言区别。下面我们就深入了解一下。

访问JavaBean中的属性

任何一个JavaBean中的属性都可以访问,不过对应的属性要提供getter方法或isProperty方法。比如:

技术分享图片
Person( age == 50 )

// 与上面拥有同样的效果
Person( getAge() == 50 )
View Code

Drools使用java标准的类检查,因此遵循java标准即可。同时,嵌套属性也是支持的,比如:

技术分享图片
Person( address.houseNumber == 50 )

// 与上面写法相同
Person( getAddress().getHouseNumber() == 50 )
View Code

在使用有状态session的情况下使用嵌套属性需要注意属性的值可能被其他地方修改。要么认为它们是不可变的,当任何一个父引用被插入到working memory中。或者,如果要修改嵌套属性值,则应将所有外部fact标记更新。在上面的例子中,当houseNumber属性值改变时,任何一个包含Address的Person需要被标记更新。

 

Java表达式

在pattern的约束条件中,可以任何返回结果为布尔类型的java表达式。当然,java表达式也可以和增强的表达式进行结合使用,比如属性访问。可以通过使用括号来更改计算优先级,如在任一逻辑或数学表达式中。

技术分享图片
Person( age > 100 && ( age % 10 == 0 ) )
View Code

也可以直接使用java提供的工具方法来进行操作计算:

技术分享图片
Person( Math.round( weight / ( height * height ) ) < 25.0 )
View Code

在使用的过程中需要注意,在LHS中执行的方法只能是只读的,不能在执行方法过程中改变改变FACT对象的值,否则会影响规则的正确执行。

技术分享图片
Person( incrementAndGetAge() == 10 ) //不要像这样在比较的过程中更新Fact对象
View Code

另外,FACT对象的相关状态除了被在working memory中进行更新操作,不应该每次调用时状态会发生变化。

技术分享图片
Person( System.currentTimeMillis() % 1000 == 0 ) // 不要这样实现
View Code

标准Java运算符优先级也适用,请参见下面的运算符优先级列表。所有的操作符都有标准的Java语义,除了==和!=。它们的null安全的,就相当于java中比较两个字符串时把常量字符串放前面调用equals方法的效果一样。

约束条件的比较过程中是会进行强制类型转换的,比如在数据计算中传入字符串“10”,则能成功转换成数字10进行计算。但如果,此时传入的值无法进行转换,比如传了“ten”,那么将会抛出异常。

逗号分隔符

逗号可以对约束条件进行分组,它的作用相当于“AND”。

技术分享图片
// Person的年龄要超过50,并且重量 超过80 kg
Person( age > 50, weight > 80 )
View Code

虽然“&&”和“,”拥有相同的功能,但是它们有不同的优先级。“&&”优先于“||”,“&&”和“||”又优先于“,”。但建议优先使用“,”分隔符,因为它更利于阅读理解和引擎的优化操作。同时,逗号分隔符不能和其他操作符混合使用,比如:

技术分享图片
Person( ( age > 50, weight > 80 ) || height > 2 ) // 会编译错误

// 使用此种方法替代
Person( ( age > 50 && weight > 80 ) || height > 2 )
View Code

绑定变量

一个属性可以绑定到一个变量:

技术分享图片
// 2 person的age属性值相同
Person( $firstAge : age ) // 绑定
Person( age == $firstAge ) // 约束表达式
View Code

前缀$只是个通用惯例,在复杂规则中可以通过它来区分变量和属性。为了向后兼容,允许(但不推荐)混合使用约束绑定和约束表达式。

技术分享图片
// 不建议这样写
Person( $age : age * 2 < 100 )

// 推荐(分离绑定和约束表达式)
Person( age * 2 < 100, $age : age )
View Code

使用操作符“==”来绑定变量,Drools会使用散列索引来提高执行性能。

 

内部类分组访问

通常情况,我们访问一个内部类的多个属性时会有如下的写法:

技术分享图片
Person( name == "mark", address.city == "london", address.country == "uk" )
View Code

Drools提供的分组访问可以更加方便进行使用:

技术分享图片
Person( name == "mark", address.( city == "london", country == "uk") )
1
View Code

注意前缀’.’是用来区分嵌套对象约束和方法调用所必需的。

内部强制转换

在使用内部类的时候,往往需要将其转换为父类,在规则中可以通过“#”来进行强制转换:

技术分享图片
Person( name == "mark", address#LongAddress.country == "uk" )
View Code

上面的例子将Address强制转换为LongAddress.,这样使得getter方法变得可用。如果无法强制转换,表达式计算的结果为false。强制转换也支持全路径的写法:

技术分享图片
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )
View Code

多次内部转换语法:

技术分享图片
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )
1
View Code

也可以使用instanceof操作符进行判断,判断之后将进一步使用该属性进行比较。

技术分享图片
Person( name == "mark", address instanceof LongAddress, address.country == "uk" )
View Code

日期字符

规则语法中除了支持JAVA标准字符,同时也支持日期字符。Drools默认支持的日期格式为“dd-mmm-yyyy”,可以通过设置系统变量“drools.dateformat”的值来改变默认的日期格式。

技术分享图片
Cheese( bestBefore < "27-Oct-2009" )
View Code

List和Map的访问

访问List:

技术分享图片
// 和childList(0).getAge() == 18效果相同
Person( childList[0].age == 18 )
View Code

根据key访问map:

技术分享图片
// 和credentialMap.get("jsmith").isValid()相同
Person( credentialMap["jsmith"].valid )
View Code

&&和||

约束表达式可以通过&&和||来进行判断比较,此处用法与标准Java相似,当组合使用时,可通过括号来划分优先级。

技术分享图片
Person( age > 30 && < 40 )
Person( age ( (> 30 && < 40) ||(> 20 && < 25) ) )
Person( age > 30 && < 40 || location == "london" )
View Code

DRL特殊操作符

“< ? > >=”操作符用于属性的比较是按照默认的排序,比如日期属性使用小于号标示可以按照日期排序,当使用在String字符串的比较时,则按照字母顺序进行排序。此操作符仅适用于可比较的属性。

技术分享图片
Person( firstName < $otherFirstName )
Person( birthDate < $otherBirthDate )
View Code

“!.”提供了一个默认空校验的操作。当使用此操作符时,会先校验当前对象是否为null,如果不为null再调用其方法或获得其属性进行判断。一旦当前操作对象为null,则相当于结果为false。

技术分享图片
Person( $streetName : address!.street )

// 上面的写法相当于
Person( address != null, $streetName : address.street )
View Code

matches操作符可使用Java的正则表达式进行字符串的匹配,通常情况下是对字符串进行匹配,但也支持变量值为正确的表达式的方式。此操作符仅适用于字符串属性。如果属性值为null,匹配的结果始终为false。

技术分享图片
Cheese( type matches "(Buffalo)?S*Mozzarella" )
View Code

not matches方法与matches相同,唯一不同的是返回的结果与之相反。

技术分享图片
Cheese( type not matches "(Buffalo)?S*Mozzarella" )
View Code

contains操作符判断一个集合属性或元素是否包含指定字符串或变量值。仅适用于集合属性。也可以用于替代String.contains()来检查约束条件。not contains用法与之相同,结果取反。

技术分享图片
CheeseCounter( cheeses contains "stilton" ) // 包含字符串
CheeseCounter( cheeses contains $var ) // 包含变量

Cheese( name contains "tilto" )
Person( fullName contains "Jr" )
String( this contains "foo" )
View Code

memberOf用来检查属性值是否为集合,此集合的表示必须为变量。not memberOf使用方法相同,结果取反。

技术分享图片
CheeseCounter( cheese memberOf $matureCheeses )
View Code

soundslike的效果与matches相似,但它用来检查一个字符串的发音是否与指定的字符十分相似(使用英语发音)。

技术分享图片
// 匹配 "fubar" 或 "foobar"
Cheese( name soundslike ‘foobar‘ )
View Code

str操作用来比较一个字符串是否以指定字符串开头或结尾,有可以用于比较字符串的长度。

技术分享图片
Message( routingValue str[startsWith] "R1" )

Message( routingValue str[endsWith] "R2" )

Message( routingValue str[length] 17 )
View Code

in和notin用来匹配一组数据中是否含一个或多个匹配的字符串,使用的方法与数据库中in的使用方法相似。待匹配的数据可以是字符串、变量。

技术分享图片
Person( $cheese : favouriteCheese )
Cheese( type in ( "stilton", "cheddar", $cheese ) )
View Code

运算符优先级

 

操作类型操作符备注
(嵌套/空安全)属性访问 .!. 非标准java语义
List/Map访问 [ ] 非标准java语义
约束绑定 : 非标准java语义
乘除 */%  
加减 +-  
移位 <<>>>>>  
关系 <>?>=instanceof  
==!= 未使用标准java语义,某些语义相当于equals。
非短路AND &  
非短路异或 ^  
非短路包含OR |  
逻辑与 &&  
逻辑或 ||  
三元运算符 ? :  
逗号分隔,相当于and , 非标准java语义








Java规则引擎的优缺点[关闭]

】Java规则引擎的优缺点[关闭]【英文标题】:ProsandconsofJavarulesengines[closed]【发布时间】:2011-01-1103:52:14【问题描述】:采用Java规则引擎JESS和Drools的优缺点是什么?还有其他玩家吗?我知道Drools是开源的,而JESS不是,但它们在... 查看详情

游戏 AI 的 Java 规则引擎

】游戏AI的Java规则引擎【英文标题】:JavaRuleEngineforGameAI【发布时间】:2010-10-0513:52:42【问题描述】:我想为我的游戏使用规则引擎。它将用于NPCAI和GMAI。为此目的,什么可能是一个好的和快速的规则引擎?它必须是Java和开源的... 查看详情

java规则引擎--drools

Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。 本文所使用的demo已上传 http... 查看详情

基于 Java 的简单规则引擎,具有后备功能

】基于Java的简单规则引擎,具有后备功能【英文标题】:Javabasedsimpleruleenginewithfallback【发布时间】:2021-01-0800:23:53【问题描述】:我需要实现一个具有分层回退支持的简单规则引擎。我已经查看了DROOLS库,但我不确定它是否支... 查看详情

Java或Python中基于开源的规则引擎[关闭]

】Java或Python中基于开源的规则引擎[关闭]【英文标题】:OpenSourcebasedRulesEnginesinJavaorPython[closed]【发布时间】:2016-03-0418:38:54【问题描述】:我正在寻找一个用Java或Python编写的规则引擎,它支持以下功能:决策表轻松创建简单的... 查看详情

几款不错的java规则引擎

以下列举几款不错的规则引擎,方便学习drools很强大的brms系统,同时生态也很不错,问题就是使用上复杂,参考https://github.com/kiegroup/drools&&https://www.drools.org/OpenLTablets参考https://github.com/openl-tablets/openl-tablets,国内资料不是... 查看详情

规则表达式引擎框架

...引擎是把字符串表达式转换为计算机可以理解运行的计算规则。表达式引擎是基于编程语言的基础之上编译原理的一种实现。     jfireEL——高性能EL表达式解析框架jfireEL是快速的EL表达式解析器,支持丰富的EL表达式,... 查看详情

规则引擎的应用

java开源的规则引擎有:Drools、EasyRules、Mandarax、IBMILOG。使用最为广泛并且开源的是Drools。     规则引擎的优点声明式编程规则可以很容易地解决困难的问题,并得到解决方案的验证。与代码不同,规则以较不复杂的语... 查看详情

springboot+drools规则引擎整合

...gBoot项目的很少。本文介绍如何在SpringBoot项目上加上Drools规则引擎。POM依赖POM文件如下:<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-insta 查看详情

drools规则引擎环境搭建(代码片段)

一、关于drools规则引擎前面写过一篇Drools规则引擎相关的文章,这篇文章主要记录一下规则引擎的环境搭建和简单示例。不熟悉drools的朋友可以看看这篇文章:自己写个Drools文件语法检查工具——栈的应用之编译器检测语法错误... 查看详情

java规则引擎《drools7.0.0.final规则引擎教程》第4章4.4约束(pattern的一部分)

4.4.3约束(Pattern的一部分)前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false的表达式,比如下面的5小于6,就是一个约束条件。Person(5<6)ViewCode从本质上来讲,它是JAVA... 查看详情

常用规则引擎

...ules首先集成了mvel表达式,后续可能集成SpEL的一款轻量级规则引擎easyrules是一个简单而强大的java规则引擎,它有以下特性:轻量级框架,学习成本低基于POJO为定义业务引擎提供有用的抽象和简便的应用从原始的规则组合成复杂... 查看详情

规则表达式引擎框架

...引擎是把字符串表达式转换为计算机可以理解运行的计算规则。表达式引擎是基于编程语言的基础之上编译原理的一种实现。     jfireEL——高性能EL表达式解析框架jfireEL是快速的EL表达式解析器,支持丰富的EL表达式,... 查看详情

java使用规则引擎drools出现异常

异常如下,但是算出来的数没有问题Exceptioninthread"Thread-16"java.lang.RuntimeException:Classnotconvertibletoprimitive:java.lang.Objectatorg.drools.core.util.ClassUtils.convertToPrimitiveType(ClassUtils.java:378)atorg.drools.rule.constraint.ConditionAnalyzer$AritmeticExpress... 查看详情

规则引擎easyrules介绍,应用及示例(代码片段)

浅析EasyRules规则引擎轻量级规则引擎EasyRulesJava规则引擎EasyRules一、EasyRules介绍1.1概述EasyRules是一个简单而强大的Java规则引擎,提供以下功能:轻量级框架和易于学习的API基于POJO的开发与注解的编程模型定义抽象的业务... 查看详情

java规则引擎---jess

如何在eclipse3.1中添加Jess7.1的JessDE?这是文档说明:TheJessDeveloper'sEnvironment(JessDE)issuppliedasasetofpluginsforthepopularopen-sourceIDEEclipse;inparticular,thesearepluginsforEclipseversion3.1orlater.NotethattheJessDEworksonlywiththefull"EclipseSDK"--thesmaller"... 查看详情

googleaviator——轻量级java表达式引擎实战(代码片段)

...擎技术及比较Drools简介Drools(JBossRules)是一个开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。除了应用了Rete核心... 查看详情

java规则引擎drools6.5.0版本中kmodule.xml解析

kmodule.xml文件存放在src/main/resources/META-INF/文件夹下。1<?xmlversion="1.0"encoding="UTF-8"?>2<kmodulexmlns="http://jboss.org/kie/6.0.0/kmodule">3<kbasename="rules"packages="rules">4<kse 查看详情