- /*
- Shopping:为订单内商品总金额大于100元的订单给与10%的折扣
- 本例要点:
- 1、语言Mvel和Java的切换
- 在Package级别定义的是Mvel语言,而在"Apply..."规则中定义的是Java语言;
- 两种语言的细节区别有很多,这里不详细说明。简单的说$c.name是Mvel语法,而$c.getName()则是Java语法
- 2、使用了not这样的非存在性逻辑,留意"Discount..."这两个规则
- 3、使用了from accumulate这种语法,accumulate的用法在手册中有详细说明
- 4、使用了insertLogical方法
- 这里留意的是"Apply..."规则插入了Discount对象,但是在代码和规则中都没有显式的删除Discount操作,
- 那"Discount removed notification"规则为何可以激活呢?
- 原因就在于insertLogical和session.retract( hatPurchaseHandle );这行代码的调用
- retract删除的对象导致"Apply..."规则激活的条件变为无效,而Discount因为是insertLogical方法加入,
- 在这种情况下自动被删除,导致了"Discount removed notification"规则激活
- 思考:
- 1、为何在执行时"Apply..."规则先于"Discount removed notification"规则调用?
- 我们知道,Drools规则引擎对规则执行冲突的解决方案如下:
- a) salience,拥有更高值的规则先激发
- b) LIFO:后进先出,这里所谓的先后是指根据Fact对象的插入顺序引发规则来计数的,越晚插入的Fact引起的规则越早执行
- c) 当LIFO顺序值相等时在Drl文件后面的规则先激发,这在Fibonacci例子中已经说明
- 现在回过头来看一下"Apply..."规则和"Discount removed..."规则,
- 激活"Apply..."规则的是最后的Purchase对象插入,因此按照LIFO原则"Apply..."规则先激发
- 假设你定义一个测试类TestRete,并在"Discount removed..."规则的条件中增加TestRete(),
- 你会发现当你将TestRete放在Purchase之后插入时,"Discount removed..."规则会先激发,这进一步验证了LIFO原则。
- */
Fact 插入
- Customer mark = new Customer( "mark",
- 0 );
- session.insert( mark );
- Product shoes = new Product( "shoes",
- 60 );
- session.insert( shoes );
- Product hat = new Product( "hat",
- 60 );
- session.insert( hat );
- session.insert( new Purchase( mark,
- shoes ) );
- FactHandle hatPurchaseHandle = session.insert( new Purchase( mark,
- hat ) );
- session.fireAllRules();
- session.retract( hatPurchaseHandle );
- System.out.println( "Customer mark has returned the hat" );
- session.fireAllRules();
规则
- package org.drools.examples
- # 定义Package中使用mvel,默认是使用java
- dialect "mvel"
- # 列出客户购买商品的情况
- rule "Purchase notification"
- salience 10
- when
- $c : Customer()
- $p : Purchase( customer == $c)
- then
- System.out.println( "Customer " + $c.name + " just purchased " + $p.product.name );
- end
- # 当给与客户折扣时显示相关信息
- rule "Discount awarded notification"
- when
- $c : Customer()
- $d : Discount( customer == $c )
- then
- System.out.println( "Customer " + $c.name + " now has a discount of " + $d.amount );
- end
- # 当折扣取消时显示相关信息
- rule "Discount removed notification"
- when
- $c : Customer()
- not Discount( customer == $c )
- then
- $c.setDiscount( 0 );
- System.out.println( "Customers " + $c.name + " now has a discount of " + $c.discount );
- end
- # 如果客户购买的商品超过100元给与折扣
- rule "Apply 10% discount if total purcahses is over 100"
- no-loop true
- dialect "java"
- when
- $c : Customer()
- $i : Double(doubleValue > 100) from accumulate ( Purchase( customer == $c, $price : product.price ),
- sum( $price ) )
- then
- $c.setDiscount( 10 );
- insertLogical( new Discount($c, 10) );
- System.out.println( "Customer " + $c.getName() + " now has a shopping total of " + $i );
- end