《Drools7.0.0.Final规则引擎教程》第4章 4.6 结果条件

结果条件

在Java中,如果有重复的代码我们会考虑进行重构,抽取公共方法或继承父类,以减少相同的代码在多处出现,达到代码的最优管理和不必要的麻烦。Drools同样提供了类似的功能。下面我们以实例来逐步说明。 像下面最原始的两条规则,有相同的业务判断,也有不同的地方:

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional1:Give 10% discount to customers older than 60"
    agenda-group "conditional1"
when
    $customer : Customer( age > 60 )
then
    modify($customer) { setDiscount( 0.1 ) };
    System.out.println("Give 10% discount to customers older than 60");
end

rule "conditional1:Give free parking to customers older than 60"
agenda-group "conditional1"
when
    $customer : Customer( age > 60 )
    $car : Car ( owner == $customer )
then
    modify($car) { setFreeParking( true ) };
    System.out.println("Give free parking to customers older than 60");
end

现在Drools提供了extends特性,也就是一个规则可以继承另外一个规则,并获得其约束条件。改写之后执行效果相同,代码如下:

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional2:Give 10% discount to customers older than 60"
    agenda-group "conditional2"
when
    $customer : Customer( age > 60 )
then
    modify($customer) { setDiscount( 0.1 ) };
    System.out.println("conditional2:Give 10% discount to customers older than 60");
end

rule "conditional2:Give free parking to customers older than 60"
    extends "conditional2:Give 10% discount to customers older than 60"
agenda-group "conditional2"
when
    $car : Car ( owner == $customer )
then
    modify($car) { setFreeParking( true ) };
    System.out.println("conditional2:Give free parking to customers older than 60");
end

我们可以看到上面使用了extends,后面紧跟的是另外一条规则的名称。这样,第二条规则同时拥有了第一条规则的约束条件。只需要单独写此条规则自身额外需要的约束条件即可。那么,现在是否是最优的写法吗?当然不是,还可以将两条规则合并成一条来规则。这就用到了do和标记。

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional3:Give 10% discount to customers older than 60"
    agenda-group "conditional3"
when
    $customer : Customer( age > 60 )
    do[giveDiscount]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional3:Give free parking to customers older than 60");
then[giveDiscount]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("conditional3:Give 10% discount to customers older than 60");
end

在then中标记了giveDiscount处理操作,在when中用do来调用标记的操作。这样也当第一个约束条件判断完成之后,就执行标记giveDiscount中的操作,然后继续执行Car的约束判断,通过之后执行默认的操作。

在then中还可以添加一些判断来执行标记的操作,这样就不必每次都执行do操作,而是每当满足if条件之后才执行:

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional4:Give 10% discount to customers older than 60"
    agenda-group "conditional4"
when
    $customer : Customer( age > 60 )
    if(type == "Golden") do[giveDiscount]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional4:Give free parking to customers older than 60");
then[giveDiscount]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("conditional4:Give 10% discount to customers older than 60");
end

同时,还可以通过break来中断后续的判断。

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional5:Give 10% discount to customers older than 60"
    agenda-group "conditional5"
when
    $customer : Customer( age > 60 )
    if(type == "Golden") do[giveDiscount10]
    else if (type == "Silver") break[giveDiscount5]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional5:Give free parking to customers older than 60");
then[giveDiscount10]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("giveDiscount10:Give 10% discount to customers older than 60");
then[giveDiscount5]
    modify($customer){
        setDiscount(0.05)
    };
    System.out.println("giveDiscount5:Give 10% discount to customers older than 60");
end

以上规则的执行测试代码如下,执行结果可自行尝试,源代码已经存放在GitHub:https://github.com/secbr/drools

后语

此系列课程持续更新中,QQ群:593177274,欢迎大家加入讨论。由于Drools资料较少,教程编写不易,每篇博客都亲身实践编写demo。如果对你有帮助也欢迎赞赏(微信)! 也是对原创的最大支持!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jerry的SAP技术分享

ABAP和Java的destination和JNDI

3563
来自专栏蘑菇先生的技术笔记

多线程中的锁系统(四)-谈谈自旋锁

2787
来自专栏草根专栏

使用angular4和asp.net core 2 web api做个练习项目(一)

这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net一样. 我用的是wind...

6785
来自专栏jeremy的技术点滴

mybatis-generator使用备忘

3644
来自专栏码匠的流水账

聊聊spring cloud gateway的RetryGatewayFilter

本文主要研究一下spring cloud gateway的RetryGatewayFilter

1552
来自专栏IT笔记

SpringBoot开发案例之整合mongoDB

JDK1.7、Maven、Eclipse、SpringBoot1.5.2、mongodb3.4,Robomongo(可视化工具)

6496
来自专栏大内老A

谈谈WCF中的Data Contract (1):Data Contract Overview

Contract in SO:Contract是对操作和数据的抽象 在我们看来,Service Orientation提供了一种对业务、功能进行分解的方式。针对...

1946
来自专栏码匠的流水账

聊聊lettuce的sentinel连接

lettuce-core-5.0.4.RELEASE-sources.jar!/io/lettuce/core/RedisClient.java

1912
来自专栏进击的程序猿

orm 系列 之 常用设计模式 The Repository Pattern

本文是orm系列的第一篇,内容来自github上的一个Markdown,清晰的讲述了一些数据库设计上常用的设计模式,并且阐述了orm是什么?

2883
来自专栏Ryan Miao

MongoDB - basic

mongoDB basic from:http://www.tutorialspoint.com/mongodb prject:https://github....

3226

扫码关注云+社区