规 则 世 界
本文的目的在于简要介绍JSR-94 JRules规范和它可能为将来的软件开发带来的影响。
程序就是去描述一个规则,而这个过程往往又是受规则控制, 我们生活在一个规则的世界里,我们的程序也是在规则的世界里(虽然有时我们不觉察),在现在业务更迭频繁的情况下,用设计模式来应对变化显得有些力不从心,对规则和机制的角度来进行抽象是软件设计发展的又一次革命性的进化。
用设计模式来应对变化的典型方法是Façade模式, 将变化封装在Session中,但是如果变化关系到另一个业务内容的变化时,代码必须修改。
如果业务对象彼此关联,那么随着程序规模的变大,对这种网络式变化的控制就会越来越复杂,会导致波纹效应,那么能不能把种规则从代码抽象出来使得它变得相对独立呢?
JSR-94即是为此而进行的。
规范的目的是定义一个轻量级的应用接口和为RULE 引擎供应商提供一个兼容的实现规范。
JRules 的主要内容:
JRules简介
JRules 是一种“判定逻辑”推理规则引擎。它采用一种占资源很少的运行时环境,这种运行时环境可以与应用程序一起部署,它为可动态更新的规则提供储存库,应用程序可以使用 JRules API 从这个储存库中提出并触发规则。JRules 提供了一个功能完备的开发环境,该环境支持规则单元测试和基于规则的应用程序的代码生成。JRules 还为生成易于使用的、基于 Web 的用于修改规则的接口提供了工具。JRules 代码生成选项包括 J2EE(Web Service 和 EJB)和简单的 J2SE。
Jrules的主要内容为:Rule Engine, Rule, Rule Execution Set, Rule Session
Rule Engine
规则引擎是底层的核心,可以看成是一个if/then 的高级解释器。
Rule
规则通常包含两个组成部分:条件和行为,当某个条件满足时,行为将被执行,规范没有规定JRULES的结构,是出于对不同供应商不同的实现的考虑,这往往是由于对引擎的不同的需求和规则算法的不同造成的,规范的目的仅仅是公布基本的元数据, 如名称和描述。
Rule Execution Set
一个execution set是一套规则的集合,规范未定义execution set的结构,仅说明了它仅由一个规则集合组成。此外,execution set同时公布基本的元数据如名称和描述。
Rule Session
一个rule session是一个在客户端和引擎间的运行时连接,一个会话与一个唯一的结果集合相联系。rule session可能占用引擎资源,但是必须在客户端不再需要Rule Session时释放。
Stateful Rule Session
有状态的rule session允许一个客户端和rule set有一个长时间的交互(有点像Stateful Session Bean),输入的对象可以再次被加入SESSION并且输出对象可以重复的被查询。
Stateless Rule Session
无状态的rule session提供了一个高效且简单的API来执行一个输入对象的List 和一个Rule execution set,并产生输出结果。Stateless rule session方法是幂等的(调用多次结果唯一,类似Stateless Session Bean 的工作方式)。
示例
一个Stateless Rule Session的示例:
// 装载一个 RuleServiceProvider ,该接口有不同的JRULES提供商实现。
Class.forName( "org.jcp.jsr94.ri.RuleServiceProvider" );
RuleServiceProvider serviceProvider =
RuleServiceProviderManager.getRuleServiceProvider( RULE_SERVICE_PROVIDER );
// 建立一个 stateless RuleSession
RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
StatelessRuleSession srs = (StatelessRuleSession)
ruleRuntime.createRuleSession( bindUri, null,
RuleRuntime.STATELESS_SESSION_TYPE );
// 执行一个规则列表
List inputList = new LinkedList();
inputList.add( new String( "Foo" ) );
inputList.add( new String( "Bar" ) );
inputList.add( new Integer( 5 ) );
inputList.add( new Float( 6 ) );
List resultList = srs.executeRules( inputList );
System.out.println( "executeRules: " + resultList );
// 释放session
srs.release();
Stateful Rule的示例:
String RULE_SERVICE_PROVIDER = "org.jcp.jsr94.jess";
// 装载一个 RuleServiceProvider
Class.forName( "org.jcp.jsr94.jess.RuleServiceProviderImpl" );
// Get the rule service provider from the provider manager.
RuleServiceProvider serviceProvider =
RuleServiceProviderManager.getRuleServiceProvider(
RULE_SERVICE_PROVIDER );
RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
一个 StatefulRuleSession示例 :
StatefulRuleSession statefulRuleSession =
(StatefulRuleSession) ruleRuntime.createRuleSession( uri,
new HashMap(),
RuleRuntime.STATEFUL_SESSION_TYPE );
// 加入一个发票对象
Invoice inputInvoice = new Invoice("Invoice");
inputInvoice.setAmount(1750);
// add an Object to the statefulRuleSession
statefulRuleSession.addObject( inputInvoice );
//execute the rules
statefulRuleSession.executeRules();
//从statefulRuleSession取出结果对象
results = statefulRuleSession.getObjects();
// 加入另外一个发票对象
Invoice inputInvoice2 = new Invoice("Invoice 2");
inputInvoice2.setAmount(3000);
//执行结果
statefulRuleSession.executeRules();
// extract the Objects from the statefulRuleSession
results = statefulRuleSession.getObjects();
// 释放 statefulRuleSession
statefulRuleSession.release();
几种规则引擎的比较
JSR-94规范是实现规则系统的一种方式,一些处于领先地位的独立软件供应商,包括 Versata、ilog 和 Blaze 都提供了规则引擎系统,其中Versata 业务对象在接口中看上像是数据库表,而规则看上去像是数据库 SQL。LOG是实现了JRules接口的产品,在 WebSphere 的
BRBeans 技术中也提供了规则引擎系统。虽然他们提供的规则引擎系统在功能和函数上各不相同,但是都提供了一些相同的功能上的好处, 使得规则相对与Business 相对独立,实现流程和结构的灵活性:
以下是规则系统的典型结构:
在可变性情况下业务策略或规则的客观化,这种情况下要将业务规则标注(call-outs)插入应用程序代码或业务流程流中。
用于以一种直观的方式表达规则的语言。
用于运行规则的执行环境。
允许用户创建和修改业务规则的工具。
规则-让世界变的简单
正如红绿灯让我们不会在马路上无所适从一样,规则也会使我们的开发变的清晰和简单,使得变化相对独立,使得我们的主要精力可以放在于规则和机制的建立而不是编写一打if/else和switch,这也正是我们真正需要关注的地方。
注:
本文中有些观点为个人看法,仅供参考。
参考资料:
1. Java Rule Engine API™ JSR-94 from http://java.sun.com/jcp/
2. XProgrammer26 <<规则对象>> from http://www.umlchina.net
3.ILog JRules Reference from http://www.ilog.com
4.<<Creating an Intelligent and Flexible Solution>> with BPM from http://www.ibm.com.