结果条件

在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博客专栏》。由于Drools资料较少,教程编写不易,每篇博客都亲身实践编写demo。如果对你有帮助也欢迎赞赏(微信)! 也是对原创的最大支持!

《Drools7.0.0.Final规则引擎教程》第4章 4.6 结果条件的更多相关文章

  1. 《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载

    在<Drools7.0.0.Final规则引擎教程>之Springboot集成中介绍了怎样将Drools与Springboot进行集成,本篇博客介绍一下集成之后,如何实现从数据库读取规则并 ...

  2. 《Drools7.0.0.Final规则引擎教程》第3章 3.1 Hello World 实例

    3.1 Hello World 实例 在上一章中介绍了Drools5x版本中规则引擎使用的实例,很明显在Drools7中KnowledgeBase类已经标注为"@Deprecated&quo ...

  3. 《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用

    2.1 Drools5简述 上面已经提到Drools是通过规则编译.规则收集和规则的执行来实现具体功能的.Drools5提供了以下主要实现API: KnowledgeBuilder Knowledge ...

  4. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE API解析

    转载至:https://blog.csdn.net/wo541075754/article/details/75004575 3.2.4 KieServices 该接口提供了很多方法,可以通过这些方法 ...

  5. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象

    转载:https://blog.csdn.net/wo541075754/article/details/74943236 3.2.1 什么是KIE KIE(Knowledge Is Everythi ...

  6. 《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE API解析

    3.2.4 KieServices 该接口提供了很多方法,可以通过这些方法访问KIE关于构建和运行的相关对象,比如说可以获取KieContainer,利用KieContainer来访问KBase和KS ...

  7. 《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象

    3.2.1 什么是KIE KIE(Knowledge Is Everything),知识就是一切的简称.JBoss一系列项目的总称,在<Drools使用概述>章节已经介绍了KIE包含的大部 ...

  8. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.1 规则文件

    转载至:https://blog.csdn.net/wo541075754/article/details/75150267 一个标准的规则文件的格式为已“.drl”结尾的文本文件,因此可以通过记事本 ...

  9. 《Drools7.0.0.Final规则引擎教程》第4章 注释&错误信息

    注释 像Java开发语言一样,Drools文件中也可以添加注释.注释部分Drools引擎是会将其忽略调的.单行注释使用"//",示例如下: rule "Testing C ...

  10. 《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)

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

随机推荐

  1. 第三方CSS安全吗?

    原文:https://jakearchibald.com/201...翻译:疯狂的技术宅 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 前一段时间,有很 ...

  2. MR案例:定制Partitioner

    可以继承基类Partitioner,也可以继承默认的HashPartitioner类,覆写其中的 getPartition() 方法实现自己的分区. 需求:本例是对上一个实例的改写,需求不变 pack ...

  3. 原生的 promise 的局限性

    本文来自:https://ekyu.moe/article/limits-of-native-promise-and-async-await/ 众所周知,Nodejs 已原生支持 Promise 和 ...

  4. POJ_2182 Lost Cows(线段树的简单应用)

    基本思路就是,从后往前读取数字small[i].在剩余编号集合里(一开始剩余编号集合为全集)查找第small[i]+1个编号,该编号就是对应位置牛的编号. 若直接用数组来做,则每次查找都需要遍历前n个 ...

  5. 记数排序 & 桶排序 & 基数排序

    为什么要写这样滴一篇博客捏...因为一个新初一问了一道水题,结果就莫名其妙引起了战斗. 然后突然发现之前理解的桶排序并不是真正的桶排序,所以写一篇来区别下这三个十分相似的排序辣. 老年菜兔的觉醒!!! ...

  6. 【Python】模块学习之利用string模块造测试数据

    背景 测试过程中需要一些随机数据,使用到了python中的string模块,记录一下 #! /usr/bin/python # coding:utf-8 """ @aut ...

  7. 微信公众平台开发(一) 配置接口与验证URL

    一.简介 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字.图片.语音的全方位沟通.互动. 二.通讯机制 三.注册微信平台 ...

  8. zDialog弹出层插件

    效果图如下: 提取自ZCMS的弹出框: 代替window.open.window.alert.window.confirm:提供良好的用户体验: 水晶质感,设计细腻,外观漂亮: 兼容ie6/7/8.f ...

  9. js中常用的字符串方法

    1,基础方法 charAt();返回该位置的字符,类似数组下标: substring();返回选中的字符,两个参数是下标. slice();参数是是一个正数,返回该数之后的剩余字符串:参数是负数,返回 ...

  10. DRUID连接池的使用

    DRUID介绍    DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控 DB池连接和SQL的执行情况,可 ...