论坛首页 Java企业应用论坛

Drools4:对Shopping示例的分析

浏览 4063 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-03  
  1. /*  
  2.     Shopping:为订单内商品总金额大于100元的订单给与10%的折扣  
  3.  
  4.     本例要点:  
  5.     1、语言Mvel和Java的切换  
  6.         在Package级别定义的是Mvel语言,而在"Apply..."规则中定义的是Java语言;  
  7.         两种语言的细节区别有很多,这里不详细说明。简单的说$c.name是Mvel语法,而$c.getName()则是Java语法  
  8.       
  9.     2、使用了not这样的非存在性逻辑,留意"Discount..."这两个规则  
  10.           
  11.     3、使用了from accumulate这种语法,accumulate的用法在手册中有详细说明  
  12.       
  13.     4、使用了insertLogical方法  
  14.         这里留意的是"Apply..."规则插入了Discount对象,但是在代码和规则中都没有显式的删除Discount操作,  
  15.         那"Discount removed notification"规则为何可以激活呢?  
  16.         原因就在于insertLogical和session.retract( hatPurchaseHandle );这行代码的调用  
  17.         retract删除的对象导致"Apply..."规则激活的条件变为无效,而Discount因为是insertLogical方法加入,  
  18.         在这种情况下自动被删除,导致了"Discount removed notification"规则激活  
  19.           
  20.     思考:  
  21.     1、为何在执行时"Apply..."规则先于"Discount removed notification"规则调用?  
  22.         我们知道,Drools规则引擎对规则执行冲突的解决方案如下:  
  23.         a) salience,拥有更高值的规则先激发  
  24.         b) LIFO:后进先出,这里所谓的先后是指根据Fact对象的插入顺序引发规则来计数的,越晚插入的Fact引起的规则越早执行  
  25.         c) 当LIFO顺序值相等时在Drl文件后面的规则先激发,这在Fibonacci例子中已经说明  
  26.           
  27.         现在回过头来看一下"Apply..."规则和"Discount removed..."规则,  
  28.         激活"Apply..."规则的是最后的Purchase对象插入,因此按照LIFO原则"Apply..."规则先激发  
  29.         假设你定义一个测试类TestRete,并在"Discount removed..."规则的条件中增加TestRete(),  
  30.         你会发现当你将TestRete放在Purchase之后插入时,"Discount removed..."规则会先激发,这进一步验证了LIFO原则。  
  31.  
  32. */  

Fact 插入

  1. Customer mark = new Customer( "mark",   
  2.                               0 );   
  3. session.insert( mark );   
  4.   
  5. Product shoes = new Product( "shoes",   
  6.                              60 );   
  7. session.insert( shoes );   
  8.   
  9. Product hat = new Product( "hat",   
  10.                            60 );   
  11. session.insert( hat );   
  12.   
  13. session.insert( new Purchase( mark,   
  14.                               shoes ) );   
  15. FactHandle hatPurchaseHandle = session.insert( new Purchase( mark,   
  16.                                                              hat ) );   
  17.   
  18. session.fireAllRules();   
  19.   
  20. session.retract( hatPurchaseHandle );   
  21. System.out.println( "Customer mark has returned the hat" );   
  22. session.fireAllRules();   

规则

  1. package org.drools.examples   
  2.   
  3. # 定义Package中使用mvel,默认是使用java   
  4. dialect "mvel"  
  5.   
  6. # 列出客户购买商品的情况   
  7. rule "Purchase notification"  
  8.     salience 10  
  9.   
  10.     when   
  11.         $c : Customer()   
  12.         $p : Purchase( customer == $c)         
  13.     then   
  14.         System.out.println( "Customer " + $c.name + " just purchased " + $p.product.name );   
  15. end     
  16.   
  17. # 当给与客户折扣时显示相关信息   
  18. rule "Discount awarded notification"  
  19.     when   
  20.         $c : Customer()   
  21.         $d : Discount( customer == $c )   
  22.     then   
  23.         System.out.println( "Customer " + $c.name + " now has a discount of " + $d.amount );   
  24. end   
  25.   
  26. # 当折扣取消时显示相关信息   
  27. rule "Discount removed notification"  
  28.     when   
  29.         $c : Customer()   
  30.         not Discount( customer == $c )   
  31.     then   
  32.         $c.setDiscount( 0 );   
  33.         System.out.println( "Customers " + $c.name + " now has a discount of " + $c.discount );   
  34. end   
  35.   
  36. # 如果客户购买的商品超过100元给与折扣   
  37. rule "Apply 10% discount if total purcahses is over 100"               
  38.     no-loop true       
  39.     dialect "java"  
  40.     when   
  41.         $c : Customer()   
  42.         $i : Double(doubleValue  > 100) from accumulate ( Purchase( customer == $c, $price : product.price ),    
  43.                                                                     sum( $price ) )   
  44.     then   
  45.         $c.setDiscount( 10 );   
  46.         insertLogical( new Discount($c, 10) );     
  47.         System.out.println( "Customer " + $c.getName() + " now has a shopping total of " + $i );   
  48. end   
   发表时间:2008-05-08  
发现一个问题,我分析了很久也没有结果,麻烦各位大虾帮想想
如果把两个Product的价格都改为160,在retract之后,居然也激活了"Discount removed notification"了这个规则,但是此时"Apply 10% discount if total purcahses is over 100"的条件依然是满足的呀,insertLogical进去的Discout对象不应该被删除的呀,很是奇怪,麻烦各位帮解答一下,谢谢了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics