规则引擎:Drools与JRuleEngine

简介: 译文:《规则引擎:Drools与JRuleEngine》译者:jacktom(chszs)作者:Vivek Tomar原文:《Rule engine : Drools / JRuleEngine》原文见http://www.naxos-software.de/blog/index.php?/archives/78-Rule-engine-Drools-JRuleEngine.html一、规则引擎规则引擎有助于基于存储在规则中的知识和推理来执行判断。
译文:《规则引擎:Drools与JRuleEngine》
译者:jacktom(chszs)
作者:Vivek Tomar
原文:《Rule engine : Drools / JRuleEngine》
原文见http://www.naxos-software.de/blog/index.php?/archives/78-Rule-engine-Drools-JRuleEngine.html

一、规则引擎
规则引擎有助于基于存储在规则中的知识和推理来执行判断。这些规则基本上只有条件和动作,别无它物。

规则引擎的优点:
1、分隔应用程序的条件和控制流
(1) 规则都存储在单独的文件。
(2) 规则可以被技术人士和商业人士修改的。
(3) 规则改变后应用程序不必重新部署。
(4) 使用集中的规则使得应用程序更易于管理和维护。

2、规则替换了代码中的if else语句
(1) 规则脚本更容易提取。
(2) 即使是非技术人员也能轻易地遵循规则。
(3) 集中可以解决问题,而不是实现。
(4) 与实现代码相比,规则聚团更容易编写。

3、为什么作决定能很容易地概念化

总结:规则有助于消除代码中大量的if else语句,使代码更易于维护。

二、Drools介绍
Drools是一个开源实现。它是一个Java库,以Apache许可证发布,其二进制代码或源码下载均有效。

推理机的核心是一个规则引擎。它执行模式匹配,在执行动作中做出决策。RETE算法用于模式匹配。

知识被表述为规则。规则有两个主要部分:条件和动作。

例如:
如果用户(年龄>17),那么System.out.println("User is greater then 17");

在人工智能系统,主要有两种响应的方法。
1、正向链(Forward Chaining)
这是基于事实根据的。在工作区域检查中规则。当规则条件为真的规则不再有时,模式匹配结束。

2、反向链(Backward Chaining)
只检查规则的动作可以匹配目标的规则。如果满足条件,然后进行评估。

3、兼容JDK1.4,且需要下面的库。
(1) drools-all-jdk1.4.2.1.jar
(2) xercesImpl-2.6.2.jar
(3) antlr-2.7.5.jar
(4) janino-2.3.2.jar

4、代码示例(ApplyRule.java)

/*
\* $Header$
*/

package com.vivek.drools.example;

import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.drools.FactException;
import org.drools.IntegrationException;
import org.drools.RuleBase;
import org.drools.WorkingMemory;
import org.drools.io.RuleBaseLoader;
import org.xml.sax.SAXException;

/**
* Demonstration of a sample rule using Java.
*
* @version <tt>$Revision: 1.0 $</tt>
* @author <a href="mailto:{vivek.tomar@naxos-software.de}" mce_href="mailto:{vivek.tomar@naxos-software.de}">{Vivek Tomar}</a>.
*/

public class ApplyRule {

// Constants -----------------------------------------------------

static Log log = LogFactory.getLog(ApplyRule.class.getName());
private static final String RULE_FILE = "/rules/rules.drl";
//private static final String RULE_IS_TURNOVER_INSURABLE = "turnoverInsurable";
//private static final String RULE_IS_TURNOVER_NOT_INSURABLE = "turnoverNotInsurable";

// Attributes ----------------------------------------------------

private double turnover = 1000000;

// Constructors --------------------------------------------------

public ApplyRule () {
try {
InputStream in = this.getClass().getResourceAsStream(RULE_FILE);
RuleBase ruleBase = RuleBaseLoader.loadFromInputStream(in);
WorkingMemory workingMemory = ruleBase.newWorkingMemory();
workingMemory.assertObject(this);
// Fire specific rule
//workingMemory.fireAllRules(new RuleNameEqualsAgendaFilter(RULE_IS_TURNOVER_INSURABLE));

//Fire all rules
workingMemory.fireAllRules();
} catch (IntegrationException e) {
e.printStackTrace();
} catch (FactException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

// Public --------------------------------------------------------

public static void main (String args[]) {
new ApplyRule();
}

public double getTurnover () {
return turnover;
}

public void setTurnover (double turnover) {
this.turnover = turnover;
}

public void printCompanyInsurable () {
log.info("******************************");
log.info("This company is Insurable.");
log.info("******************************");
}

public void printCompanyNotInsurable () {
log.info("==============================");
log.info("This company is not Insurable.");
log.info("==============================");
}
}


规则定义(rules.drl)

<?xml version="1.0"?>
<rule-set name="cheese rules"
xmlns="http://drools.org/rules"
xmlns:java="http://drools.org/semantics/java"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/rules rules.xsd
http://drools.org/semantics/java java.xsd">
<rule name="turnoverInsurable">
<parameter identifier="applyRule">
<class>com.vivek.drools.example.ApplyRule</class>
</parameter>
<java:condition>applyRule.getTurnover() > 2000000 </java:condition>
<java:consequence>
applyRule.printCompanyInsurable();
</java:consequence>
</rule>
<rule name="turnoverNotInsurable">
<parameter identifier="applyRule">
<class>com.vivek.drools.example.ApplyRule</class>
</parameter>
<java:condition>applyRule.getTurnover() < 2000000 </java:condition>
<java:consequence>
applyRule.printCompanyNotInsurable();
</java:consequence>
</rule>
</rule-set>



三、JRuleEngine介绍
JRuleEngine是一个基于Java的规则引擎,遵循JSR94规范,版本1.1。

1、JRuleEngine共同特征:
(1) 在JRuleEngine输入对象被称为事实,而输出对象被称为结论。
(2) 一个类的方法可直接从规则中调用。

2、JRuleEngine基于前向链算法。

3、规则是类org.jruleengine.rule.RuleImpl的对象,它们以下列方式载入:
(1) 可以从XML文件中读入
(2) 通过RuleImpl对象创建,也可以取自数据库。

4、会话是客户端和规则引擎之间的运行时的胶水。会话与单一的规则执行集相关。会话规则的类型:
(1) 一个有状态的规则会话可持续很长时间,可一次又一次地查询。
(2) 一个无状态的规则给出了实现,但只能持续一定时期。

5、JRuleEngine需要两个库:
(1) jsr94.jar
(2) jruleengine.jar

6、添加这些文件到您应用程序的类路径。

7、通过实例化一个有状态的规则会话(StatefulRuleSession)或无状态的规则会话(StatelessRuleSession)来使用这个库。

8、代码例子(ApplyRule.java)

/*
* $Header$
*/
package com.vivek.jruleengine.example;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.rules.RuleRuntime;
import javax.rules.RuleServiceProvider;
import javax.rules.RuleServiceProviderManager;
import javax.rules.StatelessRuleSession;
import javax.rules.admin.RuleAdministrator;
import javax.rules.admin.RuleExecutionSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Demonstration of a sample rule using Java.
*
* @version <tt>$Revision: 1.0 $</tt>
* @author <a href="mailto:{vivek.tomar@naxos-software.de}" mce_href="mailto:{vivek.tomar@naxos-software.de}">{Vivek Tomar}</a>.
*/
public class ApplyRule {

// Constants -----------------------------------------------------

static Log log = LogFactory.getLog(ApplyRule.class.getName());
private static final String RULE_FILE = "/rules/rules.xml";

// Attributes ----------------------------------------------------

private double turnover = 1000000;

// Constructors --------------------------------------------------

public ApplyRule () {

try {
// Load the rule service provider of the reference
// implementation.
// Loading this class will automatically register this
// provider with the provider manager.
Class.forName("org.jruleengine.RuleServiceProviderImpl");

// Get the rule service provider from the provider manager.
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider("org.jruleengine");

// get the RuleAdministrator
RuleAdministrator ruleAdministrator = serviceProvider.getRuleAdministrator();
log.info("Administration API");
log.info("======================");
log.info("Acquired RuleAdministrator: ");

// get an input stream to a test XML ruleset
// This rule execution set is part of the TCK.
InputStream inStream = this.getClass().getResourceAsStream(RULE_FILE);


// parse the ruleset from the XML document
RuleExecutionSet res1 =
ruleAdministrator.getLocalRuleExecutionSetProvider(null).createRuleExecutionSet(inStream, null);
inStream.close();
log.info("Loaded RuleExecutionSet: ");

// register the RuleExecutionSet
String uri = res1.getName();
ruleAdministrator.registerRuleExecutionSet(uri, res1, null);
log.info("Bound RuleExecutionSet to URI: " + uri);

RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
log.info("Acquired RuleRuntime: ");

// create a StatelessRuleSession
StatelessRuleSession statelessRuleSession = (StatelessRuleSession)
ruleRuntime.createRuleSession(uri, new HashMap(),
RuleRuntime.STATELESS_SESSION_TYPE);

log.info("Got Stateless Rule Session: " + statelessRuleSession);

// call executeRules with some input objects

// Create a input list.
List input = new ArrayList();
input.add(this);

// Print the input.
log.info("Calling rule session with the following data");
log.info("Customer turnover input: " + this.getTurnover());

// Execute the rules without a filter.
List results = statelessRuleSession.executeRules(input);

// Release the session.
statelessRuleSession.release();
log.info("Released Stateless Rule Session.");

} catch (NoClassDefFoundError e) {
if (e.getMessage().indexOf("Exception") != -1) {
log.error("Error: The Rule Engine Implementation could not be found.");
} else {
log.error("Error: " + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}

// Public --------------------------------------------------------

public static void main (String args[]) {
new ApplyRule();
}

public double getTurnover () {
return turnover;
}

public void setTurnover (double turnover) {
this.turnover = turnover;
}

public void printCompanyInsurable () {
log.info("******************************");
log.info("This company is Insurable.");
log.info("******************************");
}

public void printCompanyNotInsurable () {
log.info("==============================");
log.info("This company is not Insurable.");
log.info("==============================");
}
}


规则定义(rules.xml)

<?xml version="1.0" encoding="UTF-8"?>
<rule-execution-set>
<name>RuleExecutionSet1</name>
<description>Rule Execution Set</description>
<synonymn name="applyRule" class="com.vivek.jruleengine.example.ApplyRule" />
<rule name="turnoverInsurable" description="Check if turnover insurable" >
<if leftTerm="applyRule.getTurnover" op=">" rightTerm="2000000" />
<then method="applyRule.printCompanyInsurable()" />
</rule>
<rule name="turnoverNotInsurable" description="Check if turnover not insurable" >
<if leftTerm="applyRule.getTurnover" op="<" rightTerm="2000000" />
<then method="applyRule.printCompanyNotInsurable" />
</rule>
</rule-execution-set>


结论:
Drools除了提供正常的规则引擎的能力,还有以下额外的优点:
(1) 无论是技术人士还是商业人士,Drools都是用户友好的,它提供了一个巨大的支持工具集。
(2) Drools的Reteoo算法可加速和可扩展。
(3) Drools提供的Eclipse插件带有自动完成智能感知和调试视图、规则流GUI等。
(4) 基于Web的工具(Guvnor):是一个业务规则管理系统(BRMS),它提供了高级规则授权、版本控制和管理。

至于其他的规则引擎,我个人建议在项目中使用Drools,因为它有一个很大的支持社区。在IDE支持和基于Web的规则管理工具(Guvnor)也有很大优势。
目录
相关文章
|
算法 IDE Java
《Drools7.0.0.Final规则引擎教程》第1章 Drools简介
《Drools7.0.0.Final规则引擎教程》第1章 Drools简介
1074 0
|
算法 Java
3、Drools规则引擎-为什么选择Drools
Drools 是用 Java 语言编写的具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎 ,其基于CHARLES FORGY’S的RETE算法 符合业内标准,速度快且效率高。 业务分析师人员或审核人员可以利用它轻松查看业务规则, 检验已编码的规则执行了所需的业务规则。
202 0
|
11月前
|
存储 SQL Java
规则引擎深度对比,LiteFlow vs Drools! 下
规则引擎深度对比,LiteFlow vs Drools! 下
|
11月前
|
存储 消息中间件 JavaScript
规则引擎深度对比,LiteFlow vs Drools! 上
规则引擎深度对比,LiteFlow vs Drools! 上
1、Drools规则引擎-什么是规则引擎
### 什么是规则引擎 规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件, 实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。 接受数据输入,解释业务规则,并根据业务规则做出业务决策。
445 0
1、Drools规则引擎-什么是规则引擎
|
设计模式 数据挖掘
2、Drools规则引擎-为什么使用规则引擎
上文我们说过,规则引擎其实就是将if else全部给抽离出来了。但是这就是我们的规则引擎的全部内容吗?规则放在哪里都是放,为什么一定要拿规则引擎来抽离呢?肯定是规则引擎给我们解决了某些问题。本文主要讲的就是规则引擎是解决什么的方案
200 0
|
Java Spring
4、Drools规则引擎-Drools入门案例
Drools的实现并不难,关键是了解他的语法即可
203 0
4、Drools规则引擎-Drools入门案例
|
JSON Java 数据格式
Drools规则引擎-memberOf操作
Drools规则引擎-memberOf操作
254 0
|
Python
Drools规则引擎Map使用案例
Drools规则引擎Map使用案例
642 0
Drools规则引擎Map使用案例
|
Java API Maven
《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用
《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用
266 0
《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用