2007-08-03
Drools4:对Shopping示例的分析
关键字: drools 规则库- /*
- 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
评论
john_summer
2008-05-08
发现一个问题,我分析了很久也没有结果,麻烦各位大虾帮想想
如果把两个Product的价格都改为160,在retract之后,居然也激活了"Discount removed notification"了这个规则,但是此时"Apply 10% discount if total purcahses is over 100"的条件依然是满足的呀,insertLogical进去的Discout对象不应该被删除的呀,很是奇怪,麻烦各位帮解答一下,谢谢了
如果把两个Product的价格都改为160,在retract之后,居然也激活了"Discount removed notification"了这个规则,但是此时"Apply 10% discount if total purcahses is over 100"的条件依然是满足的呀,insertLogical进去的Discout对象不应该被删除的呀,很是奇怪,麻烦各位帮解答一下,谢谢了
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 41117 次
- 性别:

- 来自: 广州

- 详细资料
搜索本博客
我的相册
ruleflow3
共 4 张
共 4 张
最近加入圈子
最新评论
-
Drools4:对Golfer示例的 ...
对,确实是这样
-- by dong_ta -
Drools4:对Shopping示例 ...
发现一个问题,我分析了很久也没有结果,麻烦各位大虾帮想想如果把两个Product ...
-- by john_summer -
Drools4.0官方使用手册( ...
感谢!!正要把drools写进论文,需要这方面的资料
-- by gb1981 -
精品文章翻译:现实中的规 ...
jialno 写道谢谢.这段时间也在关注这东西非常感谢共享
-- by huanyouchen8312 -
Drools 4.0 BRMS使用说明
sonic_yj 写道tvjody 写道支持,国外的BRM应用都很普及了,在国内 ...
-- by 子在川上曰






评论排行榜