Drools:不逗你,直接上干货,实战分享:动态规则模板

发布一下 0 0

今天放福利干货, 由于接触到了遇到了很多关于匹配条件判断的业务场景和需求,很多人可能不假思索的就直接干if-else,可能对代码有点追求的上了层次干策略模式,噼噼啪啪绞尽脑汁设计了一啪优雅牛逼的代码接口和实现,其实做过风控系统的同学们应该对规则引擎都不陌生,可以执行百度,规则引擎有好多,传统的我曾经用过的和感觉最容易上手的当属drools了,今天就干他,分享一下

Drools:不逗你,直接上干货,实战分享:动态规则模板

直接开干


普通规则写法

先来常常鲜,堆叠式的规则写法,将所有的判断条件全部写一个规则,重复累赘

package rules;import com.example.drools.Fd.domain.TradeRecordimport java.math.BigDecimalimport org.slf4j.LoggerFactoryglobal  org.slf4j.Logger loggerrule "Between3And12"    when      trd:TradeRecord(getFqNum() >=3 && getFqNum() < 12)    then      trd.setFee(new BigDecimal("0.05").multiply(trd.getAmount()));      logger = LoggerFactory.getLogger("Drools-Between3And12");      logger.info("命中费率规则 :12期以上24期以内");endrule "Between12And24"    when      trd:TradeRecord(getFqNum() >= 12 && getFqNum() < 24)    then      trd.setFee(new BigDecimal("0.25").multiply(trd.getAmount()));      logger = LoggerFactory.getLogger("Drools-Between12And24");      logger.info("命中费率规则 :12期以上24期以内");end


今天来个进阶的,首先编写一段规则模板,对我又在用模板方式

Drools:不逗你,直接上干货,实战分享:动态规则模板

模板脚本:

这是一个根据交易分期数来匹配对应的期数费率区间,其实延伸开来,例如价格区间优化折扣、等这种带区间的需求都可以这样去实现,动态,易于维护,逻辑简单清晰易懂

package rules;dialect "java"import java.math.BigDecimalimport  com.example.drools.Fd.domain.TradeRecordimport org.slf4j.LoggerFactoryglobal  com.example.drools.Fd.domain.Fenqi fqsglobal org.slf4j.Logger loggerrule "BetweenMinAndMax"    when      trd:TradeRecord(getFqNum() >= fqs.getMin() && getFqNum() < fqs.getMax())    then      trd.setFee(new BigDecimal(fqs.getRadio()).multiply(trd.getAmount()));      logger = LoggerFactory.getLogger("Drools-BetweenMinAndMax");      logger.info("命中费率规则 : {} 期以上(包含),{} 期以内",fqs.getMin(),fqs.getMax());end

规则获取参数

  • 可以使用global关键字将java参数定义成一个全局变量参数,在整个规则中都能使用到
  • 使用 session.setGlobal("fqs",fenqishu) 传递全局参数
  • 传参,使用session.insert(tradeRecord),规则中就像java代码一样丝滑


java执行代码:

简单模拟

  • 一笔交易事实,100元的交易分了6期
  • 3期到12期之间执行的费率是0.25%
  • 命中规则,并之间计算分期费用,规则结果返回费用结果
  public void getOutRuleFiles() throws IOException {        KieServices kieServices = KieServices.Factory.get();        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();        File[] ruleFiles = Paths.get("d://temp/rules//").toFile().listFiles();        for (File file : ruleFiles) {            kieFileSystem.write(ResourceFactory.newFileResource(file));        }        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();        KieContainer kContainer = kieServices.newKieContainer(kieBuilder.getKieModule().getReleaseId());        KieBase kieBase = kContainer.getKieBase();        KieSession session = kieBase.newKieSession();        //交易事实        TradeRecord tradeRecord = new TradeRecord();                    tradeRecord.setAmount(new BigDecimal(100));                    tradeRecord.setFqNum(6);                    tradeRecord.setMerchantName("删古");        session.insert(tradeRecord);       //条件事实        Fenqi fenqishu = new Fenqi();                fenqishu.setMax(12);                fenqishu.setMin(3);                fenqishu.setRadio(0.25);        session.setGlobal("fqs",fenqishu);        session.fireAllRules();        session.dispose();        System.out.println("命中规则计费结果:"+tradeRecord.getFee());    }

工程结构:spring-boot

pom依赖

Drools:不逗你,直接上干货,实战分享:动态规则模板

总结

其实drools不是什么新技术,很老的东西了,但是网上很多用法是直接将规则写到工程本身的/main/resources/目录下,试想一下,如果这样就不太方便了,如果规则随时需要变动,那不是要重新打包吗,所以结合实践,把规则拿出来放在指定外部目录中是非常有必要的,就几行代码就能解决多少if判断,将规则做成API,也能实现解耦,技术不复杂,思路和解决方案更重要,希望对路过的朋友有所帮助。

Drools:不逗你,直接上干货,实战分享:动态规则模板

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/203978.html