规则引擎之drools

drools是一个规则引擎,能够将业务规则从代码中分离,通过修改drl配置文件即可应对不同业务需求,避免频繁上线。举例说明,如抽奖活动,规则变化仅涉及礼品类别和数量,业务数据和规则分别存储,利用drools进行判定,简化开发工作。本文包含drl配置、规则接口、接口实现、测试及执行结果的介绍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    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语法做说明,不属于本文范围

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值