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文件調用相同。