Drools简单项目

在本章中,我们将创建一个Drools项目下列问题说明:

根据不同的城市和各类产品(城和产品的组合),找出当地税务相关的城市。

我们将有两个DRL文件为我们的Drools项目。这两个文件的DRL将意味着两个城市在考虑(Pune和Nagpur)和四类产品(杂货,药品,手表和奢侈品)。

  • 在这两个城市的药品税被认为是零。
  • 杂货,我们假设了2卢比在Pune和1卢比在Nagpur的一种税。

我们已经使用了相同的售价以证明不同的输出。请注意,所有的规则都被触发了应用。

这里是模型用来保存每个项目类型:

package com.sample;

import java.math.BigDecimal;

public class ItemCity {
   public enum City {
      PUNE, NAGPUR
   }
   
   public enum Type {
      GROCERIES, MEDICINES, WATCHES, LUXURYGOODS
   }
   
   private City purchaseCity;
   private BigDecimal sellPrice;
   private Type typeofItem;
   private BigDecimal localTax;
   
   public City getPurchaseCity() {
      return purchaseCity;
   }
   
   public void setPurchaseCity(City purchaseCity) {
      this.purchaseCity = purchaseCity;
   }
   
   public BigDecimal getSellPrice() {
      return sellPrice;
   }
   
   public void setSellPrice(BigDecimal sellPrice) {
      this.sellPrice = sellPrice;
   }
   
   public Type getTypeofItem() {
      return typeofItem;
   }
   
   public void setTypeofItem(Type typeofItem) {
      this.typeofItem = typeofItem;
   }
   
   public BigDecimal getLocalTax() {
      return localTax;
   }
   
   public void setLocalTax(BigDecimal localTax) {
      this.localTax = localTax;
   }
}

DRL文件

正如前面所说,我们已经用了两个DRL文件在这里:Pune.drl 和Nagpur.drl.

Pune.drl

这是对Pune执行规则的DRL文件。

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Pune Medicine Item"
   
   when
      item : ItemCity (purchaseCity == ItemCity.City.PUNE,
                       typeofItem == ItemCity.Type.MEDICINES)
   
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Pune Groceries Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
                      typeofItem == ItemCity.Type.GROCERIES)
   
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

Nagpur.drl

这是对Nagpur市执行规则的DRL文件。

// created on: Dec 26, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Nagpur Medicine Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
                      typeofItem == ItemCity.Type.MEDICINES)

   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Nagpur Groceries Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
                      typeofItem == ItemCity.Type.GROCERIES)

   then
      BigDecimal tax = new BigDecimal(1.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

我们已经写了基于城市的DRL文件,因为它为我们提供了可扩展性,以在以后添加任意数量的规则文件,如果被添加了新的城市。

为了证明所有的规则都可以从我们的规则文件触发,我们已经使用了两种类型的产品(药物和杂货); 药是免税和杂货征税按城市。

我们的测试类加载规则文件,插入事实到会话,并产生输出。

Droolstest.java

package com.sample;

import java.math.BigDecimal;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;

import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;

import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import com.sample.ItemCity.City;
import com.sample.ItemCity.Type;

/* This is a sample class to launch a rule. */

public class DroolsTest {
   public static final void main(String[] args) {
      try {
      
         // load up the knowledge base
         KnowledgeBase kbase = readKnowledgeBase();
         StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
         
         ItemCity item1 = new ItemCity();
         item1.setPurchaseCity(City.PUNE);
         item1.setTypeofItem(Type.MEDICINES);
         item1.setSellPrice(new BigDecimal(10));
         ksession.insert(item1);
         
         ItemCity item2 = new ItemCity();
         item2.setPurchaseCity(City.PUNE);
         item2.setTypeofItem(Type.GROCERIES);
         item2.setSellPrice(new BigDecimal(10));
         ksession.insert(item2);
         
         ItemCity item3 = new ItemCity();
         item3.setPurchaseCity(City.NAGPUR);
         item3.setTypeofItem(Type.MEDICINES);
         item3.setSellPrice(new BigDecimal(10));
         ksession.insert(item3);
         
         ItemCity item4 = new ItemCity();
         item4.setPurchaseCity(City.NAGPUR);
         item4.setTypeofItem(Type.GROCERIES);
         item4.setSellPrice(new BigDecimal(10));         
         ksession.insert(item4);
         
         ksession.fireAllRules();
         
         System.out.println(item1.getPurchaseCity().toString() + " " 
            + item1.getLocalTax().intValue());
         
         System.out.println(item2.getPurchaseCity().toString() + " "
            + item2.getLocalTax().intValue());
         
         System.out.println(item3.getPurchaseCity().toString() + " "
            + item3.getLocalTax().intValue());
         
         System.out.println(item4.getPurchaseCity().toString() + " "
            + item4.getLocalTax().intValue());
                            
      } catch (Throwable t) {
         t.printStackTrace();
      }
   }
   
   private static KnowledgeBase readKnowledgeBase() throws Exception {
   
      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
      
      kbuilder.add(ResourceFactory.newClassPathResource("Pune.drl"), ResourceType.DRL);
      kbuilder.add(ResourceFactory.newClassPathResource("Nagpur.drl"), ResourceType.DRL);
      
      KnowledgeBuilderErrors errors = kbuilder.getErrors();
      
      if (errors.size() > 0) {
         for (KnowledgeBuilderError error: errors) {
            System.err.println(error);
         }
         throw new IllegalArgumentException("Could not parse knowledge.");
      }
      
      KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
      kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
      
      return kbase;
   }
}

如果你运行这个程序,它的输出将如下所示:

PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

对于这两种Pune的和Nagpur,当时该项目是一个医药,当地税务为零;而当该项目是一个杂货店的产品,该税是按城市的。更多的规则可以在DRL文件的其他产品中添加。这仅仅是一个示例程序。

调用外部函数形成DRL文件

在这里,我们将演示如何从DRL文件的Java文件调用静态函数。

首先,创建一个类HelloCity.java在同一个包com.sample中。

package com.sample;

public class HelloCity {
   public static void writeHello(String name) {
      System.out.println("HELLO " + name + "!!!!!!");
   }
}

此后,添加import语句在DRL文件来调用从DRL文件writeHello方法。在下面的代码块中,修改DRL文件Pune.drl以黄色突出显示。

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;
 
import com.sample.HelloCity;

//declare any global variables here
dialect "java"

rule "Pune Medicine Item"

   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, typeofItem == ItemCity.Type.MEDICINES)

   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
      HelloCity.writeHello(item.getPurchaseCity().toString());
end

rule "Pune Groceries Item"

   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, typeofItem == ItemCity.Type.GROCERIES)
   
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

再次运行程序,其输出将如下所示:

HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

现在,在输出的差被标记为黄色,显示在Java类的静态方法的输出。

其优点调用Java方法是,我们可以用Java编写的任何效用/辅助函数,并从DRL文件调用相同。


上一篇: Drools规则语法 下一篇: Drools调试