- Drools 教程
- Drools - 首頁
- Drools - 簡介
- Drools - Eclipse 外掛
- Drools - 執行時
- Drools - 建立 Drools 程式
- Drools - 常用術語
- Drools - 規則編寫
- Drools - 規則語法
- Drools - Drools 示例程式
- Drools - 除錯
- Drools 有用資源
- Drools - 快速指南
- Drools - 有用資源
- Drools - 討論
Drools - Drools 示例程式
本章我們將為以下問題建立一個 Drools 專案:
根據城市和產品型別(城市和產品的組合),找出該城市的當地稅。
我們的 Drools 專案將有兩個 DRL 檔案。這兩個 DRL 檔案將分別代表兩個城市(浦那和納格浦爾)和四種類型的產品(食品雜貨、藥品、手錶和奢侈品)。
這兩個城市藥品的稅收均為零。
對於食品雜貨,我們假設浦那的稅收為 2 盧比,納格浦爾的稅收為 1 盧比。
我們使用了相同的售價來演示不同的輸出。請注意,應用程式中所有規則都會被觸發。
這是用於儲存每個 itemType 的模型:
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
這是執行浦那市規則的 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
這是執行納格浦爾市規則的 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
對於浦那和納格浦爾,當商品為藥品時,當地稅為零;而當商品為食品雜貨時,稅收則根據城市而定。可以在 DRL 檔案中為其他產品新增更多規則。這只是一個示例程式。
從 DRL 檔案呼叫外部函式
在這裡,我們將演示如何從 DRL 檔案中呼叫 Java 檔案中的靜態函式。
首先,在同一個包 `com.sample` 中建立一個名為 `HelloCity.java` 的類。
package com.sample;
public class HelloCity {
public static void writeHello(String name) {
System.out.println("HELLO " + name + "!!!!!!");
}
}
然後,在 DRL 檔案中新增 import 語句以從 DRL 檔案呼叫 writeHello 方法。在下面的程式碼塊中,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 檔案中呼叫它。