drools是一个规则引擎,可以将开发从业务中解放出来,不用重复写不同的业务、然后测试、上线,只需要将业务规则配置到drl文件,然后每次有新业务需求的时候,只需要改一下配置文件,项目不需要重新上线。drools帮你装载规则,解析规则,应用规则到你的业务。总之,使用drools你可以将业务规则的判定放在引擎里面去做,程序中只保留需要的业务数据。
比如抽奖,其实抽奖每次规则都是差不多的,无非就是换个规则,比如新手大礼包,过生日,过节,然后就是礼品的类目、数量会变化,我们将这些业务数据放到facet里面,然后将规则配置到drl文件中,然后每次修改drl规则文件,拿到刚才说的那些业务数据,利用drools装载的规则进行判断,看用户是否中奖。
这里提供一个例子,是活动相关的,根据数据的初始值匹配规则、执行规则、产生结果。
1.drl配置文件
package promotionRule;
import mydrools.Promotion;
rule step1
salience 100
lock-on-active true
when
$promotionRule : Promotion(getPurchaseNum()== 0&&getGoodsName()=="机油")
then
$promotionRule.setPurchaseNum($promotionRule.getPurchaseNum()+10);
$promotionRule.recordPointLog("只要是机油,就买10件");
end
rule step2
salience 99
lock-on-active true
when
$promotionRule : Promotion(goodsPrice < 100)
then
$promotionRule.setPurchaseNum($promotionRule.getPurchaseNum()+50);
$promotionRule.recordPointLog("价格小于100,就多买50件");
end
rule step3
//活动期限内,多买10件
salience 90
lock-on-active true
date-effective "2017-01-08 23:59:59"
date-expires "2017-08-08 23:59:59"
when
$promotionRule : Promotion(getPurchaseNum() < 1)
then
$promotionRule.setPurchaseNum($promotionRule.getPurchaseNum()+100);
$promotionRule.recordPointLog("活动期限内,怎么着多买100件");
end
2.规则接口
public interface PromotionEngineRule {
void initEngineRule();
void executeEngineRule(Promotion prmotion);
void refreshEngineRule();
}
3.接口实现
public class PromotionEngineRuleImpl implements PromotionEngineRule {
private KnowledgeBase knowledgeBase;
@Override
public void initEngineRule() {
System.out.println(" init start.....");
// 设置时间格式
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
knowledgeBase=getKnowledgeBase();
System.out.println(" init end");
}
@Override
public void executeEngineRule(Promotion promotion) {
StatefulKnowledgeSession sessions= knowledgeBase.newStatefulKnowledgeSession();
sessions.insert(promotion);
sessions.fireAllRules(new AgendaFilter() {
@Override
public boolean accept(Activation activation) {
boolean result=false;
if(activation.getRule().getName()!=null) {
result= true;
}
return result;
}
});
sessions.dispose();
}
@Override
public void refreshEngineRule() {
System.out.println("refresh start ...");
for(KnowledgePackage k:knowledgeBase.getKnowledgePackages()){
knowledgeBase.removeKnowledgePackage(k.getName());
}
initEngineRule();
System.out.println("refresh end");
}
public static KnowledgeBase getKnowledgeBase(){
List<String> paths=getRulePath();
KnowledgeBuilder builder= KnowledgeBuilderFactory.newKnowledgeBuilder();
for(String path:paths){
builder.add(ResourceFactory.newClassPathResource(path), ResourceType.DRL);
}
KnowledgeBuilderErrors errors=builder.getErrors();
if(errors.size()>0){
for(KnowledgeBuilderError error:errors){
System.out.println(error);
}
throw new IllegalArgumentException("can not parse knowledge");
}
KnowledgeBase kbase= KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(builder.getKnowledgePackages());
return kbase;
}
public static List<String> getRulePath(){
List<String> paths= Lists.newArrayList();
paths.add("rules/promotionRule.drl");
return paths;
}
}
4.测试
public class PromotionTest {
public static void main(String[] args){
Promotion p=new Promotion();
PromotionEngineRule engine=new PromotionEngineRuleImpl();
p.setPurchaseNum(0);
p.setGoodsName("机油");
p.setGoodsPrice(10);
engine.initEngineRule();
engine.executeEngineRule(p);
engine.refreshEngineRule();
}
}
5.执行结果
init start.....
16:01:52,049 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
……..
init end
只要是机油,就买10件,已买数量10
价格小于100,就多买50件,已买数量60
活动期限内,怎么着多买100件,已买数量160
refresh start ...
init start.....
init end
refresh end
本文没有对drools语法做说明,不属于本文范围