我们的日常生活是由规则驱动的。每次我们在开车的时候停在红灯处,之所以这样做,因为我们遵循一条规则,灯变红时我们应该停下来。如果你跳起来,最终会落到地面,这是由地球引力所决定的,它可以被表示成简单的数学方程。然而,对于我们生活日常中的规则,我们使用更加简单的结构来表示:当 XXX 的时候,做 XXX 的事。

1 2

when 满足什么样的条件 then 最终结果

在程序中普遍的存在一些业务逻辑规则。比如下面的代码:

1 2 3

if (){} else if (){} else {}

在这些规则不变的情况下,我们的程序能完成正常的需求规则。但是程序中的一些规则经常是需要变动的,这些变动我们可以通过代码来更改。但是往往一些需求规则变动太频繁,常改代码不是常事,因此我们需要一种更灵活的方法来实现。在这时 Drools 规则引擎框架诞生了,它能极大的方便我们更改一些程序中的规则。

Drools 简介

JBoss Rules 的前身是Codehaus的一个开源项目叫 Drools。最近被纳入JBoss门下,更名为JBoss Rules,成为了JBoss应用服务器的规则引擎。

Drools 是为 Java 量身定制的基于Charles Forgy的RETE算法的规则引擎的实现。具有了OO接口的RETE,使得商业规则有了更自然的表达。

Drools 的用 XML 的、 节点表达If–Then句式,而里面可以嵌入上述语言的代码作为判断语句和执行语句。

其中 Java 代码会使用Antlr进行解释,而 Groovy 和 Python 本身就是脚本语言,可以直接调用。

Drools 的聪明之处在于,用 XML 节点来规范 If–Then 句式和事实的定义,使引擎干起活来很舒服。

而使用 Java,Groovy等原生语言来做判断和执行语句,让程序员很容易过渡、移植,学习曲线很低。

下面我们进入实战系列,实现一个手机话费的例子。

定义规则

首先要分析自己的业务逻辑,根据业务而制定出不同的规则,这里我们假设有3个规则。

对于新开户的手机用户送20元话费。

在2014年10月到12期间充值的用户,不论金额多少充值满3次就赠送5元话费。

当月充值金额达到100以上,每达到一次赠送话费10元。

Drools 教程

分析这些规则,并把他们抽象成一个 EntityRule 对象。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

package com.core.drools; import java.util.UUID; /** * EntityRule-Model * @author www.xttblog.com */ public class EntityRule { private String username; private boolean account; private int addtime; private double currentmoney; private double totailaddmoney; public void getSerialnumber(String username, double currentmoney){ System.out.println( "Account:" +username+ " Balance:¥" +currentmoney); System.out.println( "Serial Number:" +UUID.randomUUID().toString()); } }

定义规则引擎

业务和规则都整理清楚了我们就可以开始规则引擎的核心部分啦,这里我定义的是接口和实现类。

1 2 3 4 5 6 7 8 9 10

package com.core.drools; /** * RuleEngine-Interface * @author www.xttblog.com */ public interface RuleEngine { public void init(); public void refresh(); public void execute( final EntityRule entityRule); }

实现规则引擎

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

package com.core.drools; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; import org.drools.RuleBase; import org.drools.StatefulSession; import org.drools.compiler.DroolsParserException; import org.drools.compiler.PackageBuilder; import org.drools.rule.Package; import org.drools.spi.Activation; /** * RuleEngine-Implements * @author www.xttblog.com */ public class RuleEngineImpl implements RuleEngine{ private RuleBase ruleBase; @Override public void init() { System.setProperty( "drools.dateformat" , "yyyy-MM-dd HH:mm:ss" ); ruleBase =SingleRuleFactory.getRuleBase(); try { PackageBuilder backageBuilder = getPackageBuilderFile(); ruleBase.addPackages(backageBuilder.getPackages()); } catch (DroolsParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } @Override public void refresh() { ruleBase = SingleRuleFactory.getRuleBase(); Package[] packages = ruleBase.getPackages(); for (Package items :packages){ ruleBase.removePackage(items.getName()); } init(); } @Override public void execute( final EntityRule entityRule) { if ( null == ruleBase.getPackages() || 0 == ruleBase.getPackages().length) { return ; } StatefulSession statefulSession = ruleBase.newStatefulSession(); statefulSession.insert(entityRule); statefulSession.fireAllRules( new org.drools.spi.AgendaFilter() { public boolean accept(Activation activation) { return !activation.getRule().getName(). contains( "_test" ); } }); statefulSession.dispose(); } private PackageBuilder getPackageBuilderFile() throws Exception { List drlFilePath = getRuleFile(); List readers = loadRuleFile(drlFilePath); PackageBuilder backageBuilder = new PackageBuilder(); for (Reader r : readers) { backageBuilder.addPackageFromDrl(r); } if (backageBuilder.hasErrors()) { throw new Exception(backageBuilder.getErrors().toString()); } return backageBuilder; } private List loadRuleFile(List drlFilePath) throws FileNotFoundException { if ( null == drlFilePath || 0 == drlFilePath.size()) { return null ; } List readers = new ArrayList(); for (String ruleFilePath : drlFilePath) { readers.add( new FileReader( new File(ruleFilePath))); } return readers; } private List getRuleFile(){ List drlFilePath = new ArrayList(); String path="D:/utils/my/DroolsProject/src/ com/core/drools/drools_rule.drl"; drlFilePath.add(path); return drlFilePath; } }

再定义一个单例的RuleBase工厂类。

1 2 3 4 5 6 7 8 9 10 11 12

package com.core.drools; import org.drools.RuleBase; import org.drools.RuleBaseFactory; /** * @author www.xttblog.com */ public class SingleRuleFactory { private static RuleBase ruleBase; public static RuleBase getRuleBase(){ return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase(); } }

编写规则文件

规则文件可以根据自己的业务需求定义多个文件,这里我只定义了一个。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

package com.core.drools import com.core.drools.EntityRule; rule accountEntity //One salience 100 lock-on-active true when $entityRule : EntityRule(account == true) then System.out.println("The new account:Present¥20.0"); $entityRule.setCurrentmoney($entityRule.getCurrentmoney()+20); $entityRule.getSerialnumber($entityRule.getUsername(),$entityRule.getCurrentmoney()); System.out.println(); end rule billEntity //two salience 99 lock-on-active true date-effective "2014-010-01 00:00:00" date-expires "2014-012-31 23:59:59" when $entityRule : EntityRule(addtime >= 3) then System.out.println("Prepaid phone numberreach "+$entityRule.getAddtime()+" times:Present ¥"+$entityRule.getAddtime()/3*5); $entityRule.setCurrentmoney($entityRule.getCurrentmoney()+$entityRule.getAddtime()/3*5); $entityRule.getSerialnumber($entityRule.getUsername(),$entityRule.getCurrentmoney()); System.out.println(); end rule addMoney //Three salience 98 lock-on-active true when $entityRule : EntityRule(totailaddmoney >= 100) then System.out.println("The account for the month top-up totail amount is "+$entityRule.getTotailaddmoney()+":Present ¥"+(int)$entityRule.getTotailaddmoney()/100*10); $entityRule.setCurrentmoney($entityRule.getCurrentmoney()+(int)$entityRule.getTotailaddmoney()/100 * 10);$entityRule.getSerialnumber($entityRule.getUsername(),$entityRule.getCurrentmoney()); end

测试引擎

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

package com.test; import java.io.IOException; import com.core.drools.EntityRule; import com.core.drools.RuleEngine; import com.core.drools.RuleEngineImpl; /** * Test Drools * @author www.xttblog.com */ public class DroolsTest { public static void main(String[] args) throws IOException { RuleEngine engineImpl = new RuleEngineImpl(); engineImpl.init(); final EntityRule entityRule= new EntityRule(); entityRule.setCurrentmoney(350d); entityRule.setUsername( "Candy" ); entityRule.setAccount( true ); entityRule.setTotailaddmoney(350d); entityRule.setAddtime( 7 ); engineImpl.execute(entityRule); } }

测试结果

1 2 3 4 5 6 7 8 9 10 11

The new account:Present ¥20.0 Account:Candy Balance:¥370.0 Serial Number:0fd98593-caa2-444d-a4ff-b4001cfb3260 ------------------------------------------------------------------------------ Prepaid phone number reach 7 times:Present ¥10 Account:Candy Balance:¥380.0 Serial Number:a118b211-c28e-4035-aa60-2f417f62b2f3 ------------------------------------------------------------------------------ The account for the month top-up totail amount is 350.0: Present ¥30 Account:Candy Balance:¥410.0 Serial Number:2bfc02c2-267f-47a2-9cda-5a4196e2b7cf

Drools 规则引擎就是这么简单,在实际的程序中能帮助我们解决很多现实问题。

java营销活动动态引擎规则_JAVA规则引擎 Drools 教程相关推荐

  1. java引擎组件_Java 脚本引擎入门

    Java Script Engine Java 脚本引擎可以将脚本嵌入Java代码中,可以自定义和扩展Java应用程序,自JDK1.6被引入,基于Rhino引擎,JDK1.8后使用Nashorn引擎, ...

  2. java静态和动态的区别_Java 静态与动态的区别

    Java 静态与动态的区别 1.静态的属性是类共同拥有的,而动态的属性是类各对象独立拥有的. 2.静态上内存空间上是固定的,动态中内存空间在各个附属类里面分配. 3.分配顺序不同,先分配静态对象的空间 ...

  3. java中注解动态传参_Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)...

    Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)java 前言:因为前段时间忙于写接口,在接口中须要作不少的参数校验,本着简洁.高效的原则,便写了这个小工具供本身使 ...

  4. java数组的四个要素_Java零基础系列教程04Java数组

    配套视频教程 问题Java考试结束后,老师给张浩分配了一项任务,让他计算全班(30人)的平均分int stu1 = 95; int stu2 = 89; int stu3 = 79; int stu4 ...

  5. java基本数据类型与封装类 示例_Java零基础系列教程10Java抽象与封装

    配套视频教程 软件出现的目的 用计算机的语言描述现实世界 用计算机解决现实世界的问题 为什么使用面向对象 世界由对象组成 面向对象的思想 描述 面向对象的世界 符合人类思维习惯 从现实中抽象出类分三步 ...

  6. 如何从容的应对营销活动奖励发放

    来源:一个数据人的自留地 01 前言 常见的营销活动,总结来看就是"在各种限制条件下对于适合的人群进行适合的激励,从而完成拉新.促活等阶段性目标从而促成盈利".每次进行的营销活动涉 ...

  7. 只看活动结案报告?营销活动效果你还能做的更好

    随着食品饮料行业销量增速下行,品牌主纷纷开始尝试快速迭代新产品,期望以产品升级的方式迎合消费者需求,通过营销手段的创新,在激烈的市场竞争中,抢占更有利的行业地位.一些品牌开始投入到微信.微博.KOL等 ...

  8. java 实现规则引擎_Java规则引擎 Easy Rules

    1.  Easy Rules 概述 Easy Rules是一个Java规则引擎,灵感来自一篇名为<Should I use a Rules Engine?>的文章 规则引擎就是提供一种可选 ...

  9. 如何构建营销活动平台(四):规则引擎设计

    前言 前面将活动抽象成了规则检验和一系列的操作,不同的活动的规则有重叠也有不同,如何设计才能保证最好的扩展性. 规则引擎的出现就是制定一套规则检验的模型,下面来看下具体的设计. 核心UML图 组件介绍 ...

  10. java开源规则引擎比较_规则引擎对比

    RuleEngine--一款使用简单,入门方便的数据库规则引擎_Rewen的专栏-CSDN博客_rulesengine https://blog.csdn.net/Rewen/article/deta ...

最新文章

  1. 案例 | 铅酸蓄电池精细维护
  2. 用Elasticsearch代替数据库存储日志方式
  3. 疯狂软件对Oracle放弃Java EE的看法
  4. Java编程:弗洛伊德算法(无向图所有顶点最小路径)
  5. Spring bean 通过实现 InitializingBean ,DisposableBean 接口实现初始化方法和销毁前操作
  6. 使用Android 实现计算器功能
  7. 修改树莓派默认密码及切换root账号
  8. android win7 共享网络打印机,详解win7共享打印机如何设置
  9. cm12 系统字体更换
  10. winedit使用教程_基础教程:BCDEDIT常用命令及使用实例(图)
  11. Linux学习~树莓派gpio控制
  12. Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“(已解决)
  13. 我的世界服务器显示披风指令,我的世界电脑披风指令 | 手游网游页游攻略大全...
  14. 手把手教你做蓝牙聊天应用(二)-设计方案
  15. OSChina 周三乱弹 —— 啪啪啪是敲键盘的声音
  16. 【列表的使用】用python完成购物打印商品列表
  17. 大话设计模式读书笔记之原型模式
  18. 基于PowerDC的直流压降仿真及整改分析
  19. 网络连接里面是空白的没有什么的本地连接、interface:没有注册类别
  20. 【计算机网络相关】内网穿透介绍

热门文章

  1. linux脚本取消空格,Shell去除空格和空行的方法
  2. 影视剪辑,PR剪辑软件两个转场教程
  3. 中国的北斗,世界的北斗|hightopo卫星发射demo
  4. html的跳转页面代码
  5. Java快递物流运输管理系统源码
  6. WFDB工具箱在Matlab2010b及更高版本上的安装
  7. win10 下mysql环境变量配置
  8. CCNA考试题库中英文翻译版及答案16
  9. 如何减少linux内存碎片
  10. 【视频编码格式】全面解析