【Mastering JBoss Drools 6】笔记 基本属性

Drools Runtime

主要介绍Drools的组件是如何工作的,它们各个组件的职责,和他们的配置,本章重点介绍如下:
•    了解Drools是怎么运行的
•    常用的配置
•    使用KieScanner加载动态的规则变化

为了生成规则引擎的新实例,我们需要理解一下概念

•     KieServices
•     KieContainer
•     KieModule
•     KieBase
•     KieSession

我们先从KieServices开始,它是提供注册服务的,通过它可以访问到上面所有的类,我们用下面的静态方法调用就可以拿到它

KieServices kss = KieServices.Factory.get();

通过它,我们可以访问规则引擎里面的一系列工厂,服务和引擎.

 

Rule attributes

enable  它来控制规则不可用,该属性一般是动态去定义,比如全局变量传进来的值,或者某个属性

rule "attribute"
  enabled false
  agenda-group "group001"
    when
    then
      System.out.println("group 001 is used");
end

salience 控制优先级,再同时满足条件的多个rule中,salience数值越大,执行的越靠前

rule "Classify Item - Mid/High Range (special)"
salience 10
    when
        $i: Item( cost > 300 && cost < 400 )
    then
        $i.setCategory(
        Item.Category.SPECIAL_MIDHIGH_RANGE);
        update($i);
end

activation-group 当同一个activation-group里面的规则有很多个并且同时满足条件的时候,drools只会执行它们中的其中一个

agenda-group 每一个rule都有一个agenda-group,默认的是MAIN,通过它可以给不同的业务场景设置不同的agenda-group,因为是按业务分组,所以经常会跟salience一起使用

 

no-loop 在某些场景下,比如一个规则被执行后,有一个修改操作,但是修改后的结果仍然满足当前的规则条件,那么又会执行该规则,最坏的情况就是进入死循环状态,这个属性就是告诉该规则只会被当前调用者执行一次

rule "Classify Item - Mid/High Range (special)"
no-loop
salience 10
    when
        $i: Item( cost > 300 && cost < 400 )
    then
        $i.setCategory(
        Item.Category.SPECIAL_MIDHIGH_RANGE);
        update($i);
end

agenda-group 规则分组,比如我们现实生活中的商城,有满减活动优惠规则,有积分优惠规则,有会员又会规则,通过它对规则进行分组,有利于去和相应的业务分开.

rule "Promotion: more than 10 pencils get 10% discount"
agenda-group "promotions"
    when
        OrderLine(item.name == "pencil", quantity > 10)
    then
        insert(new Discount(0.10));
end
KieSession ksession = ...;
ksession.getAgenda().getAgendaGroup("promotions").setFocus();
ksession.fireAllRules();

date-effective /date-expires 执行时间,有效期和过期时间,比如商城的假日优惠活动,这个时间段才会启动,其它时间段是不执行的,那么这个就到了很好的作用 

rule "Add special tax of 3%"
    date-effective "01-Jan-2015"
    date-expires "31-Dec-2020"
    when $i: Item()
    then $i.setSalePrice($i.getSalePrice() * 1.03);
end

Lock-on-active 最简单的理解方式就是解决no-loop解决不了的事情,no-loop没办法阻止两个rule之间循环调用,代码如下, rule1执行完之后执行rule2,rule2执行完之后执行rule1,所以no-loop只能解决自身的循环调用,不能解决多个rule的相互循环调用.

rule "Give extra 2% discount for orders larger
no-loop true
    when $o: Order(totalItems > 15)
    then modify ($o) { increaseDiscount(0.02);
end

rule "Give extra 2% discount for orders larger
no-loop true
    when $o: Order(total > 100.00)
    then modify ($o) { increaseDiscount(0.02);
end

以下的写法可以解决no-loop解决不了的问题:

rule "Give extra 2% discount for orders larger than $100"
lock-on-active true
    when $o: Order(total > 100.00)
    then modify ($o) { increaseDiscount(0.02); }
end

通过属性去控制规则,在现实生活中,比如以下场景,优惠活动,有满100优惠和满5件商品优惠,但是此优惠是二选一不能同步享受,这时候可以通过实体类的属性来判断规则的执行(这个不可取,会造成实体类中出现一些额外的字段去存储这些值,然后增加维护成本):

rule "Add 2% discount for orders larger than $100"
    when $o:
        Order(total > 100.00, has100DollarsDiscount == false)
    then
        modify($o){
        increaseDiscount(0.02);
        setHas100DollarsDiscount(true);
}
end
rule "Add 2% discount for orders larger than 15 items"
    when $o:
        Order(total > 100.00, has15ItemsDiscount == false)
    then
        modify($o){
        increaseDiscount(0.02);
        setHas15ItemsDiscount(true);
}
end

Declared types 类型声明:在其内部,可以定义对象属性(比如String)和基础类型(如long), 他们可以继承其它的类型声明,它甚至可以申明一些自定义的实体类,你可以通过getter/setter(rule engine 自动生成)方法去访问它

package person;
import com.drools.entities.Person
dialect  "mvel"

 declare specialPerson extends Person
    person: Person
    company: String
    level: int
 end

java代码设置和获取值的方法

    @Test
    public void testDeclare() {
        try {
            FactType type = ks.getKieBase().getFactType(
                    "person", "specialPerson");
            Object instance = type.newInstance();
            type.set(instance, "company", "backstop");
            type.set(instance, "level", 99);
            Object company = type.get(instance, "company");
            Object level = type.get(instance, "level");
            System.out.println(company.toString());
            System.out.println(level.toString());

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

property-reactive beans 目前不是很清楚,英文中提到和no-loop和lock-on-active类似

package person.reactive;
dialect  "mvel"
import com.drools.entities.Person


 declare specialPerson extends Person
    @propertyReactive
    person: Person
    company: String
    level: int
 end

 rule "Larger than 20 items orders are special orders"
   when
     $o: specialPerson(
     level > 3
     ) @Watch (!person)
   then
     modify ($o) {
     setPerson(new Person("Depu", 99, Person.GENDER_MALE, ".."))
     }
 end
   @Test
    public void testReactive() throws Exception {
        FactType type = ks.getKieBase().getFactType("person.reactive", "specialPerson");
        Object person = type.newInstance();
//        type.set(person, "company", "backstop");
        type.set(person, "level", 5);

        ks.insert(person);
        int count = ks.fireAllRules();
        System.out.println("total run " +count+ " rules");
        Person result = (Person) type.get(person, "person");
        System.out.println("result:" + result);
    }
global 定义全局变量
global java.util.List list
rule "match all famale by from"
    when
      Company($persons: persons)
      $p:Person(gender == Person.GENDER_FEMALE) from $persons
    then
      System.out.println("girl'name is " + $p.getName());
end
        ks.setGlobal("list", persons);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值