Drools入门
文章转载自:http://cwqcwq.iteye.com/blog/397869
一、背景知识:
1、什么是规则引擎
Java规则引擎起源于基于规则的专家系统,而基于规则的专家系统又是专家系统的其中一个分支。专家系统属于人工智能的范畴,它模仿人类的推理方式,使用试探性的方法进行推理,并使用人类能理解的术语解释和证明它的推理结论。
推理引擎包括三部分:模式匹配器(Pattern Matcher)、议程(Agenda)和执行引擎(Execution Engine)。推理引擎通过决定哪些规则满足事实或目标,并授予规则优先级,满足事实或目标的规则被加入议程。模式匹配器决定选择执行哪个规则,何时执行规则;议程管理模式匹配器挑选出来的规则的执行次序;执行引擎负责执行规则和其他动作。
和人类的思维相对应,推理引擎存在两者推理方式:演绎法(Forward-Chaining)和归纳法(Backward-Chaining)。演绎法从一个初始的事实出发,不断地应用规则得出结论(或执行指定的动作)。而归纳法则是根据假设,不断地寻找符合假设的事实。Rete算法是目前效率最高的一个 Forward-Chaining推理算法,许多Java规则引擎都是基于Rete算法来进行推理计算的。
推理引擎的推理步骤如下:
(1)将初始数据(fact)输入Working Memory。
(2)使用Pattern Matcher比较规则库(rule base)中的规则(rule)和数据(fact)。
(3)如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合。
(4)解决冲突,将激活的规则按顺序放入Agenda。
(5)使用执行引擎执行Agenda中的规则。重复步骤2至5,直到执行完毕所有Agenda中的规则。
上述即是规则引擎的原始架构,Java规则引擎就是从这一原始架构演变而来的。
Drools是基于正向推理的规则引擎。正向推理是数据驱动的,facts事实被传递到工作空间中,在那里有一个或多个规则与这些事实匹配,并由Agenda安排执行—我们从一个事实开始,传递事实,最后得到一个结论。
产生式规则是一个用一阶逻辑进行知识呈现的二元结构。
when
then
Drools中的Rete算法被称为ReteOO,表示Drools为面向对象系统(Object Oriented systems)增强并优化了Rete算法。
2、规则引擎的优点
声明式编程:使用规则更加容易对复杂的问题进行表述,并得到验证
逻辑与数据分离:数据保存在系统对象中,逻辑保存在规则中。这根本性的打破了面向对象系统中将数据和逻辑耦合起来的局面
速度及可测量性:Drools的Rete、Leaps算法,提供了对系统数据对象非常有效率的匹配,这些算法经过了大量实际考验的证明
3、何时使用
业务逻辑经常发生改变
代码中有很多”if””else””switch”和其它凌乱的逻辑,且总是易变的
二、开始
目前drools的最新版本是5.0(2009年5月19日发布),本文使用4.0.7。
1、导入jar包:
drools-core-4.0.7.jar
drools-compiler-4.0.7.jar
antlr3-runtime-3.0
mvel-1.3.1-java1.4
core-3.2.3.v_686_R32x :在eclipse中编译.drl文件时需要
2、从HelloWorld开始:
一个通用的规则引擎类:
- import java.io.InputStreamReader;
- import java.io.Reader;
- import org.drools.RuleBase;
- import org.drools.RuleBaseFactory;
- import org.drools.WorkingMemory;
- import org.drools.compiler.DroolsParserException;
- import org.drools.compiler.PackageBuilder;
- import org.drools.event.DebugWorkingMemoryEventListener;
- import org.drools.rule.Package;
- public class RuleEngine {
- private RuleBase rules;
- private boolean debug = false;
- public RuleEngine(String rulesFile) throws DroolsParserException {
- super();
- try {
- //读取规则文件,*.drl
- Reader source = new InputStreamReader(RuleEngine.class.getResourceAsStream("/" + rulesFile));
- //PackageBuilder用来构建Package
- PackageBuilder builder = new PackageBuilder();
- //解析和编译规则文件
- builder.addPackageFromDrl(source);
- //获取包中的规则集合
- Package pkg = builder.getPackage();
- //RuleBase是运行时组件,包含一个或多个Package
- rules = RuleBaseFactory.newRuleBase();
- rules.addPackage(pkg);
- } catch (Exception e) {
- throw new DroolsParserException("Could not load/compile rules file: " + rulesFile, e);
- }
- }
- public void executeRules(WorkingEnvironmentCallback callback) {
- WorkingMemory workingMemory = rules.newStatefulSession();
- if (debug) {
- workingMemory.addEventListener(new DebugWorkingMemoryEventListener());
- }
- callback.initEnvironment(workingMemory);//用来向Working Memory中设置Facts对象
- workingMemory.fireAllRules();//触发规则引擎
- }
- }
- import java.io.InputStreamReader;
- import java.io.Reader;
- import org.drools.RuleBase;
- import org.drools.RuleBaseFactory;
- import org.drools.WorkingMemory;
- import org.drools.compiler.DroolsParserException;
- import org.drools.compiler.PackageBuilder;
- import org.drools.event.DebugWorkingMemoryEventListener;
- import org.drools.rule.Package;
- public class RuleEngine {
- private RuleBase rules;
- private boolean debug = false;
- public RuleEngine(String rulesFile) throws DroolsParserException {
- super();
- try {
- //读取规则文件,*.drl
- Reader source = new InputStreamReader(RuleEngine.class.getResourceAsStream("/" + rulesFile));
- //PackageBuilder用来构建Package
- PackageBuilder builder = new PackageBuilder();
- //解析和编译规则文件
- builder.addPackageFromDrl(source);
- //获取包中的规则集合
- Package pkg = builder.getPackage();
- //RuleBase是运行时组件,包含一个或多个Package
- rules = RuleBaseFactory.newRuleBase();
- rules.addPackage(pkg);
- } catch (Exception e) {
- throw new DroolsParserException("Could not load/compile rules file: " + rulesFile, e);
- }
- }
- public void executeRules(WorkingEnvironmentCallback callback) {
- WorkingMemory workingMemory = rules.newStatefulSession();
- if (debug) {
- workingMemory.addEventListener(new DebugWorkingMemoryEventListener());
- }
- callback.initEnvironment(workingMemory);//用来向Working Memory中设置Facts对象
- workingMemory.fireAllRules();//触发规则引擎
- }
- }
3、编写drl文件:test.drl
- package org.drools.tutorials.banking
- "
- when
- String (toString=="jack") //含义:如果插入的Facts对象是String类型,且调用其toString()方法后的值等于"jack",则为true
- then
- System.out.println("HelloWorld!");
- end
- package org.drools.tutorials.banking
- "
- when
- String (toString=="jack") //含义:如果插入的Facts对象是String类型,且调用其toString()方法后的值等于"jack",则为true
- then
- System.out.println("HelloWorld!");
- end
4、测试:
- public class Test {
- public static void main(String[] args) {
- RuleEngine engine = null;
- try {
- engine = new RuleEngine("test.drl");
- } catch (DroolsParserException e) {
- // process Exception
- }
- engine.executeRules(new WorkingEnvironmentCallback(){
- public void initEnvironment(WorkingMemory workingMemory) throws FactException {
- workingMemory.insert("jack"); //向Working Memory中设置Facts对象
- }
- });
- }
- }
- public class Test {
- public static void main(String[] args) {
- RuleEngine engine = null;
- try {
- engine = new RuleEngine("test.drl");
- } catch (DroolsParserException e) {
- // process Exception
- }
- engine.executeRules(new WorkingEnvironmentCallback(){
- public void initEnvironment(WorkingMemory workingMemory) throws FactException {
- workingMemory.insert("jack"); //向Working Memory中设置Facts对象
- }
- });
- }
- }
三、简单介绍
1、术语解释
Rule:一条规则可以看作是IF…THEN…语句块,或者一个简单的IPO(即输入、处理和输出),描述了一组输入,一组判断和一组输出;
RuleBase: RuleBase包含一个或多个规则包,它们已经被校验和编译完成,是可以序列化的
Package: 规则包,是规则以及其它相关结构的一个集合,包必须有一个名称空间,并且使用标准的java约定进行命名
WorkingMemory: 用户工作区,包含用户的数据和相关Rule的引用
Facts: Facts就是规则中用到的输入,Facts可以是任何规则可以存取的Java对象,规则引擎完全不会克隆对象,它仅仅是保存对对象的一个引用/指针
2、规则文件详解
规则文件通常是以drl扩展名结尾。在一个drl文件中可以包含多个规则,函数等等,DRL是简单的text文件格式。
规则文件的构成:
package package-name //定义包名
imports //导入java包
globals //定义全局变量,如 global java.util.List myGlobalList;
functions //定义函数
rules //一系列的规则
规则的构成:
rule "name"
attributes
when
LHS
then
RHS
end
说明:
LHS是规则的条件部分,可以定义变量
RHS是允许Java语义代码,RHS中的多条语句实质上是一个规则,只有满足全部语句才符合规则
任何在LHS中绑定的变量可以在RHS中使用
3、规则文件示例解读
rule “Rule 01”
when
//$date定义一个变量,其值为Cashflow对象getDate()的值
//$cashflow定义一个指向Cashflow对象的引用
$cashflow : Cashflow( $date : date, $amount : amount )
not Cashflow( date < “27-Oct-2007”) //not 意为不存在,只有不存在date < “27-Oct-2007″的Cashflow对象才为true
then
System.out.println(“Cashflow: “+$date+” :: “+$amount);
$cashflow.setAmount($cashflow.getAmount()+$amount); //设置Cashflow对象的amount值
retract($cashflow);//当retract一个fact,WorkingMemory将不再跟踪该fact
end
public class Cashflow {
private Date date;
private double amount;
//省略getter.. setter..
}
重要:规则引擎完全不会克隆对象,它仅仅是保存对对象的一个引用/指针
即,在规则定义中对fact的修改,就是对代码中fact对象的修改。
也即,规则的根本目的是产生一个供使用的输出结果,即修改后的JavaBean
Drools入门的更多相关文章
- drools入门示例
Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效.随着互联网金融的兴 ...
- Drools规则引擎
一.简介 Drools is a Business Rules Management System (BRMS) solution. It provides a core Business Rules ...
- drools的简单入门案例
一.背景 最近在学习规则引擎drools,此处简单记录一下drools的入门案例. 二.为什么要学习drools 假设我们存在如下场景: 在我们到商店购买衣服的时候,经常会发生这样的事情,购买1件不打 ...
- Drools 6.5 Final 入门
Drools 6.5 Final学习笔记 最近项目中要涉及到使用规则对数据进行操作,想到自己实现一个完整且能灵活满足业务需求的规则系统太难了,就想了解一下有没有开源的规则引擎可以使用,后来发现Droo ...
- Drools规则引擎入门指南(三)——使用Docker部署Workbench
其实本来我也是打算使用Tomcat来部署Workbench的,但是在网上看了几篇文章,超级繁琐的配置.各种版本.实在看不下去了索性就直接使用Docker来部署了.本次部署的版本是最新稳定版,对应dro ...
- Drools规则引擎入门指南(二)
本篇博客主要讲解Drools常用的属性以及函数 属性 首先我们在resources\rules文件夹下创建一个Property.drl,还有一个DroolsApplicationPropertyTes ...
- Drools规则引擎入门指南(一)
最近项目需要增加风控系统,在经过一番调研以后决定使用Drools规则引擎.因为项目是基于SpringCloud的架构,所以此次学习使用了SpringBoot2.0版本结合Drools7.14.0.Fi ...
- Drools笔记:初识与入门
Drools是什么? Drools是一个用Java编写的开源规则引擎,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境 ...
- Drools文档(六) 用户手册
用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...
随机推荐
- 驱动中遍历模块,以及获取ntoskrnl.exe基址
方法是基于PsLoadModuleList方式 驱动中遍历模块 一丶简介 简介: 进入内核了.遍历内核中使用的模块该怎么办. 其实在驱动中.我们的DriverEntry入口位置. 提供了两个参数. 一 ...
- js 数组元素位置互换
如下实现的是,先将数组反转,然后将第二个元素与倒数第三个元素位置互换 ,,,,,,,); arr.reverse(); two=arr.splice(,,); three=arr.splice(-,, ...
- UDF——提取指定线上随时间变化的物理量
Fluent版本:Fluent 19.0 Visual Studio版本:Visual Studio 2013 有时候我们想要实现一些功能,比如:我们在使用Fluent进行瞬态计算的时候,想要获取某条 ...
- [BUAA软工]beta阶段贡献分
团队成员在Beta阶段的角色和具体贡献: 名字 角色 具体的可衡量的可验证的贡献 zpj 前段+ 前后端对接 博客X1 20+ commits ui 设计与实现 bug fixed: 2 推广:10 ...
- Sql Server 2008 R2安装教程
作者:骄阳似火_2018 来源:CSDN 原文:https://blog.csdn.net/weixin_42773514/article/details/87008537 版权声明:本文为博主原创文 ...
- Struts2工作原理和核心文件
一.Struts2工作原理 如下图: 二.Struts2配置文件 1.web.xml 任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只有配置了web.xml文件的Servl ...
- Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization
Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization 2019-10-10 10:50:19 Paper ...
- JMH java基准测试
Measure, don’t guess! JMH适用场景 JMH只适合细粒度的方法测试 原理 编译时会生成一些测试代码,一般都会继承你的类 maven依赖 <dependencies> ...
- systemctl start docker失败,提示start request repeated too quickly for docker.service
情景说明 本来服务器docker服务运行的很好,但客户重启了服务器-于是服务有些问题,遂进入到服务器再次启动docker及服务.不料提示上面的错误-- 解决办法 尝试1 Google了一圈,发现说法很 ...
- Selenium+Java完整框架搭建(2019完整版)
一.WebDriver框架开发实战 1.框架的思想 (1)什么是框架? 框架是可以被应用开发者定制的应用骨架 (2)为什么要写框架? 提高脚本可维护性 提高编写脚本的速度 提高脚本可阅读性 (3)框架 ...