Drools 5 模板技术应用(drools template)

引用自[http://cutelion.blog.hexun.com/72268803_d.html]

开发环境: Drools 5.3.0, 必需的lib: drools-templates-5.3.0.Final.jar

在利用Drools 5编写规则时,如果发现有一组规则遵守相同布置的模式、约束和在RHS中的动作,只是
常量、对象或字段名字不同,可以考虑为产生实际的规则,启用Drools的规则模板功能。我们可以编写一个
规则模板文件,包含规则文字骨架,并使用Drools模板编译器,为实例规则的内容组合一个提供实际值的对
象集合。以下是一个简单的例子。

1. 新建一个java包,如 template
2. 在其中建枚举: ItemCode.java

package template;

public enum ItemCode {
LOCK, STOCK, BARREL
}


3. 建一个项目类 Item.java

package template;

public class Item {
private String name;
private int weight;
private ItemCode itemCode;
private int price;

public Item(String name, int price, int weight, ItemCode itemCode) {
super();
this.name = name;
this.price = price;
this.weight = weight;
this.itemCode = itemCode;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}

public ItemCode getItemCode() {
return itemCode;
}

public void setItemCode(ItemCode itemCode) {
this.itemCode = itemCode;
}

public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}



4. 建一个参数集的类: ParamSet.java

package template;

import java.util.EnumSet;

public class ParamSet {
private String field;
private int lower;
private int upper;
private EnumSet<ItemCode> codeSet;

public ParamSet(String field, int lower, int upper,
EnumSet<ItemCode> codeSet) {
super();
this.field = field;
this.lower = lower;
this.upper = upper;
this.codeSet = codeSet;
}

public String getField() {
return field;
}

public int getLower() {
return lower;
}

public int getUpper() {
return upper;
}

public String getCodes() {
StringBuilder sb = new StringBuilder();
String conn = "";
for (ItemCode ic : codeSet) {
sb.append(conn).append(" == ItemCode.").append(ic);
conn = " ||";
}
return sb.toString();
}
}



5. 建一个规则展开器类,用于展开模板规则。Expander.java

package template;

import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.Collection;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.template.ObjectDataCompiler;

public class Expander {
public void expand(KnowledgeBase kBase, InputStream is, Collection<?> act)
throws Exception {
ObjectDataCompiler converter = new ObjectDataCompiler();
String drl = converter.compile(act, is);
KnowledgeBuilder kBuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
Reader rdr = new StringReader(drl);
kBuilder.add(ResourceFactory.newReaderResource(rdr), ResourceType.DRL);
if (kBuilder.hasErrors()) {
for (KnowledgeBuilderError err : kBuilder.getErrors()) {
System.err.println(err.toString());
}
throw new IllegalStateException("DRL errors");
}
kBase.addKnowledgePackages(kBuilder.getKnowledgePackages());
}
}



6. 建一个规则模板文件: Item.drl

template header
field
lower
upper
codes

package range;

import template.Item
import template.ItemCode

template "inRange"
rule "is in range @{row.rowNumber}"
when
Item($name : name, $v : @{field} >= @{lower} && <= @{upper}, $code : itemCode @{codes})
then
System.out.println("Item " + $name + " @{field} in range: " + $v + " itemCode: " + $code);
end
end template


说明: $code : itemCode @{codes} 中的 @{codes} 是应用的 getCodes()方法, 拼接了字符串形成一个带或(||)的逻辑表达式。也就是 Item.getCodes()这个方法。

7. 到这里就可以开始写测试代码了。TestItemTemplate.java

package template;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;

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

public class TestItemTemplate {
public static void main(String args[]) throws Exception {
Collection<ParamSet> cfl = new ArrayList<ParamSet>();
cfl.add(new ParamSet("price", 10, 50, EnumSet.of(ItemCode.BARREL)));
cfl.add(new ParamSet("weight", 10, 99, EnumSet.of(ItemCode.LOCK,ItemCode.STOCK)));
KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
Expander ex = new Expander();
InputStream dis = ResourceFactory.newClassPathResource("template/Item.drl", TestItemTemplate.class).getInputStream();
ex.expand(kBase, dis, cfl);
StatefulKnowledgeSession session = kBase.newStatefulKnowledgeSession();

session.insert(new Item("A", 130, 42, ItemCode.LOCK));
session.insert(new Item("B", 44, 140, ItemCode.STOCK));
session.insert(new Item("C", 23, 80, ItemCode.BARREL));
session.insert(new Item("D", 85, 9, ItemCode.LOCK));
session.insert(new Item("E", 146, 189, ItemCode.STOCK));
session.insert(new Item("F", 16, 90, ItemCode.STOCK));
session.insert(new Item("G", 44, 140, ItemCode.BARREL));
session.fireAllRules();
}
}



得出如下测试结果:
Item G price in range: 44 itemCode: BARREL
Item F weight in range: 90 itemCode: STOCK
Item C price in range: 23 itemCode: BARREL
Item A weight in range: 42 itemCode: LOCK
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值