Drools扫盲普及贴
一花一世界,一叶一菩提
一 前言
最早对Drools感兴趣,是起源于规则引擎.当时是希望能找一个开源工具来做一些规则的处理.
在官方网站上翻了半天资料,却发现Drools一直在强调它不只是一个简单的规则引擎,而是更多的引入工作流的概念.
之后最大的感触就是Drools牵涉到的东西比较多,甚至有一种依照Drools可以创造整个世界的感觉-- 这个世界本身不就是由各种规则/流程/事件构成的么? 这也是本文标题的由来.
以后会对Drools的各方面有一个比较深入的了解,因此这篇文章只是用来做简单的介绍,希望能在短时间内能让其他人对Drools做什么,怎么做,有一个直观的了解,以后遇到相关应用的场景时,能想到Drools的解决方案.
PS:PPT是在Team内部的团队分享时使用的,有一些链接可能会失效(外网无法访问).本文内容和PPT不会完全一致.不过问题不大了.
二.从规则引擎的应用场景说起
昨天讲解PPT的时候有人问到Drools和If-else的本质区别在哪里.我想了想,还是想引用一句话来表述自己的感受.
"南京一高职学生为了给男友发鲸鱼宝宝的短信涉嫌伪造健康证明捐精买iphone4。。。。"
2.1 各种棋类游戏
象棋围棋五子棋跳棋军棋扑克牌三国杀杀人游戏强权外交等等等等.游戏本身就是规则的代名词.
2.2 业务规则
超市打折,汇率计算等等等等.
2.3 相通的场景
这些场景可能有一些相通的点,在这儿我可能总结的不会太全面,稍稍罗列一下:
单条规则相对简单 规则数量相对庞大 规则之间会有冲突 一条规则本身会触发另一条规则 规则有可能会产生变动(很多时候可能唯一需要变动的就是规则)
这个时候用规则引擎来处理这些事情就相对来说容易多了.不过,Drools做的远远不止这些.
三 Drools的构成.
目前Drools的最新稳定版本是5.2.0.Final(23-Jun-2011). 现在由JBoss维护,分成五个模块.
下面就简单的介绍下每一个模块的内容,可以大致的了解下Drools的发展方向和可以用来解决问题的范畴.
3.1 Guvnor
Guvnor是一个通过Web界面可以管理,更改规则的工具,也可以提供Repository的服务.(似乎各种开源软件里都会提供这样的Web管理界面,Heritrix,Nutch,AllGeography等等等等).支持Dsl和QA.
3.2 Expert
传统的规则引擎,应该说Drools的核心,也是前身.通过Rete算法来实现模式匹配.
3.3 Jbpm5
工作流的处理交给了JBPM5这个模块.这个模块我了解的不多,大概知道的是除了工作流之外还提供了各种各样的集成(Camel,Spring,Osgi等等,感觉这个模块本身的规划不是特别清晰).其中Camel适用于路由转发.有了解的较多的朋友可以指教一下,或者以后有时间我会再了解一下相关的内容.
3.4 Fusion
用于做CEP的处理.本来是不太懂CEP的,这个概念接触的不算多.不过看到了Wiki上的一个例子,大概明白一些.
摘录如下:
Expert还是核心,Fusion和Planer和Workflow都应该是规则的应用到具体领域的扩展,通过JBPM5还提供了和各种开源软件的集成.Guvnor来提供各种资源的管理.
四 Expert
对Expert有了解就可以使用Drools了.所以我想还是总体的介绍下Expert的使用,这样具体的细节其他朋友可以通过翻阅手册来自己解决了.
列出几个知识点:
1.Drl文件.
Drl就是Drools用来描述规则的文件.DRL文件的结构包括以下几部分:
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add(ResourceFactory.newClassPathResource("demo.drl"), ResourceType.DRL);KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();Employee employee=new Employee("段三品");employee.setClockedAt(System.currentTimeMillis());ksession.insert(employee);ksession.fireAllRules();
Session分成两种,一种是StateFul,一种是StateLess.区别是StateFul是可以完成推理的,即一条规则有可能导致另一条规则的触发,因此需要显示的调用一下FireAllRules().而StateLess是不支持规则推理的.所以规则是自动触发.
Employee 是一个简单的Demo类,用来表示一个员工.这里想给出的是一个判断员工上班是否迟到的示例,因此Employee可以设计成这个样子.
import java.io.Serializable;import org.apache.commons.lang.builder.ToStringBuilder;import org.apache.commons.lang.builder.ToStringStyle;public class Employee implements Serializable{/** * */private static final long serialVersionUID = -2301765612395462099L;private String name;private Long clockedAt;private boolean late;public String getName() {return name;}public void setName(String name) {this.name = name;}public Long getClockedAt() {return clockedAt;}public void setClockedAt(Long clockedAt) {this.clockedAt = clockedAt;}public boolean isLate() {return late;}public void setLate(boolean late) {this.late = late;}public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); }} rule "迟到"lock-on-activewhen $employee: Employee(clockedAt > 9:00 )then $employee.setLate(true); end
[when]When the credit rating is {rating:ENUM:Applicant.creditRating} = applicant:Applicant(creditRating=="{rating}") [then]Approve the loan = applicant.setApproved(true) [when]When the applicant dates is after {dos:DATE:default} = applicant:Applicant(applicationDate>"{dos}") [when]When the applicant approval is {bool:BOOLEAN:checked} = applicant:Applicant(approved=={bool}) [when]When the ages is less than {num:1?[0-9]?[0-9]} = applicant:Applicant(age<{num})