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調試