规则引擎Drools简明教程.docx
- 文档编号:11735191
- 上传时间:2023-03-31
- 格式:DOCX
- 页数:13
- 大小:30.16KB
规则引擎Drools简明教程.docx
《规则引擎Drools简明教程.docx》由会员分享,可在线阅读,更多相关《规则引擎Drools简明教程.docx(13页珍藏版)》请在冰豆网上搜索。
规则引擎Drools简明教程
规则引擎Drools简明教程
什么是Drools
Drools是一个基于CharlesForgy's的Rete算法的,专为Java语言所设计的规则引擎。
Rete算法应用于面向对象的接口将使基于商业对象的商业规则的表达更为自然。
Drools是用Java写的,但能同时运行在Java和.Net上。
Drools
Drools被设计为可插入式的语言实现。
目前规则能用Java,Python和Groovy实现。
更为重要的是,Drools提供了声明式程序设计(DeclarativeProgramming),并且使用域描述语言(DomainSpecificLanguages(DSL))-专为你的问题域定义了某种模式的Xml,它已经足够灵活到可以用来描述你的问题域。
DSLs包含的XML元素(Element)和属性(Attribute)代表了问题域中各种要素。
这段时间企业级Java简直能让你睡着。
有多少J2EE-EJB应用程序只是从网页提取数据并把它们存入到数据库中?
但开发者真正应该开发和维护的却是他们应用程序中复杂的商业逻辑。
这个问题不仅仅适用于将要新应用,而且渐渐地,也适用于那些长期运行的商业核心应用,它们的内部逻辑也需要经常改变,而且往往要求在一个非常短的时间内。
在以前的文章中,“用Drools让你的商业逻辑使用框架”,我介绍了Drools框架,展示了它如何用来组织复杂的商业逻辑。
Drool用一组简单的,众所周知的事物替换了许多缠杂的if…then表达式。
如果你经历过和商业客户的会议,并为他们提出的想要实现的东西的复杂程度搞得头痛,或许你应该考虑一下像Drools这样的规则引擎了。
这篇文章将向你展示如何在企业级Java应用中使用Drools.
一路到底的框架
大多数开发者都有自己喜爱的框架。
无特定顺序,它们包括表现层框架(Struts,JSF,Cocoon和Spring),持久化框架(JDO,Hibernate,CayenneandEntityBeans)以及结构框架(EJB,又是Spring,Pico和Excalibur),还有其它很多。
每种框架都各有所长,给开发者提供子许多“即开即用”的功能。
使用框架来部署应用意味着你避免了许多让人厌烦的细节,让你集中注意力到关键之处。
到目前为直,在框架所能做的事中仍然有一个缺口,那就是商业逻辑没有框架。
像EJB和Spring这样的工具虽好,但它们却几乎没有提及怎么组织你的那些if…then语句。
把Drools加到你的开发工具箱中意味着现在你可以“一路到底”的使用框架来构建你的应用程序。
图1显示了这样的一个应用
图1.用于Java应用的框架
这篇文章将基于我们已经了解的Drools框架的功能,这些功能可以让我们构建这样的一个应用。
]
我什么时候应该使用规则引擎?
“如果你有一把锤子,那所有的东西都看起来都像钉子”,这句话在软件工程领域几乎成了陈词滥调了。
虽然规则引擎能解决我们的许多问题,但确实值得认真考虑一下规则引擎对我们的企业级Java应用是否合适。
需要问的问题有:
●我的应用程序有多复杂?
对于那些只是把数据从数据库中传入传出,并不做更多事情的应用程序,最好不要使用规则引擎。
但是,当在Java中有一定量的商业逻辑处理的话,可以考虑Drools的使用。
这是因为很多应用随着时间的推移越来越复杂,而Drools可以让你轻松应对这一切。
●我的应用的生命周期有多久?
这个问题的正确答案往往是“令人惊讶的长”――还记得那些认为他们的程序不会苟活到2000年的大型机的程序员吗?
使用规则引擎将会在中长期得到好处。
像这篇文章所展示的那样,甚至原型都能从Drools与灵活方法的组合中获益,让“原型系统”转化成生产系统。
●我的应用需要改变吗?
唯一能确定的是你的需求将会改变,无论是在开发过程中或是在开发完成以后。
Drools使用一个或多个简单易配的XML文件帮你来应对这一切。
那么性能呢?
如果你正在写一个企业级应用,很有可能它会扩展到成百(如果不是成千)的用户。
你已经知道现有的Java和J2EE应用能做到这一点,但一个使用了Drools的应用对这一压力的表现如何?
答案是:
“令人吃惊的好”。
大多数开发者只是因为不愿“失控”而依赖于他人的代码(比如:
某种框架),想想这个:
Drools不仅可以让你的应用和“传统”的编程方法一样快,甚至可以更快,看下面:
●避免糟糕的代码:
Drools引导开发者去做“正确的事”。
你可以确定你正在写的代码是好的,但你的开发伙伴呢?
你可以同样这样说吗?
使用框架可以让你更轻松地写出更快,更好的代码。
●优化过的框架:
你有多少次看见商业逻辑重复地从数据库中提取相同的信息,从而降低了整个应用的速度?
如果正确使用的话,Drools不仅仅能够记住信息,而且还能记住以往使用该信息进行测试的结果,从而大幅提升应用的速度。
●Rete算法:
很多次我们并不是真正需要使用“if”条件。
被Drools实现的Rete算法,可以用一个优化的方法替换掉所有的“if…then”表达式。
需要重点提及的是:
Rete算法在使用更多的内存来降低运行时延迟方面作了折衷。
当然这在现代的应用服务器中并不是一个问题,我们也并不推荐你在移动手机上使用Drools!
规则引擎——Drools2实例应用指南
本文给出了如何利用Drools来执行业务规则实例。
在将这个例子之前,我先简单的介绍规则引擎的工作步骤。
1)加载rul规则描述脚本:
RuleBasebusinessRules=RuleBaseLoader.loadFromUrl(url);
2)设置传递到url脚本的参数实例:
WorkingMemoryworkingMemory=businessRules.newWorkingMemory();
workingMemory.assertObject(xxx);
3)执行规则:
workingMemory.fireAllRules(filter);//filter规则为过虑器
rul的语法比较简单,从以下例子中就能体会出来,这里不讲述了。
考虑这样一种情况,某学校USST希望招收的学校其年龄应该大于15岁,另外一个学校FUDAN希望其招收的学生大于18岁.当然,不同的学校对学生的要求可能不一样,例如年龄、性别、成绩等。
如果采用大量的if...else语句写在业务逻辑层,将来随着学校招生的要求变化,需要应用程序开发人员,不断的修改业务规则。
现在考虑采用Drools来使商务逻辑从应用程序中分离出来。
1。
首先设计一个Student类,包括姓名、年龄、性别、希望就读学校。
类文件如下:
packagecom.primeton.juxtapose.rule.example;
/**
*简单的JavaBean保存student值。
用于存放与学生相关的信息。
*包括姓名、年龄、性别、是否推荐入学等。
*
*根据学生的性别、年龄等判断该学生是否可以入读某一学校。
*如:
某女子学校可能只接受性别为女的学生;
*某学校可能只接受年龄大于15岁的学生入学;
*某女子学校可能只接受性别为女且年龄大于18岁的学生入学;
*......
*
*@authorliuxiang
*
*/
publicclassStudent{
//常量
publicfinalstaticStringYES="YES";
publicfinalstaticStringNO="NO";
//内部变量
privateStringstudentName=null;
privateintstudentAge=0;
privateStringstudentSex=null;
privateStringrecommend=null;
privateStringschoole=null;
/**
*设置学生姓名
*@paramstudentName
*/
publicvoidsetStudentName(StringstudentName){
this.studentName=studentName;
}
/**
*获得学生姓名
*@return
*/
publicStringgetStudentName(){
returnthis.studentName;
}
/**
*设置学生年龄
*@paramstudentAge
*/
publicvoidsetStudentAge(intstudentAge){
this.studentAge=studentAge;
}
/**
*获得学生年龄
*@return
*/
publicintgetStudentAge(){
returnthis.studentAge;
}
/**
*设置学生性别
*@paramstudentSex
*/
publicvoidsetStudentSex(StringstudentSex){
this.studentSex=studentSex;
}
/**
*获得学生性别
*@return
*/
publicStringgetStudentSex(){
returnthis.studentSex;
}
/**
*设置是否推荐入学
*@paramrecommend
*/
publicvoidsetRecommend(Stringrecommend){
this.recommend=recommend;
}
/**
*获得是否推荐入学
*@return
*/
publicStringgetRecommend(){
returnthis.recommend;
}
/**
*设置孩子希望就读的学校
*@paramschoole
*/
publicvoidsetSchoole(Stringschoole){
this.schoole=schoole;
}
/**
*获得孩子希望就读的学校
*@return
*/
publicStringgetSchoole(){
returnthis.schoole;
}
}
2。
对于业务逻辑考虑用一个简单得Java类来实现,用来模拟执行商业逻辑。
类BusinessLogicLayer,用于模拟商业逻辑的执行。
packagecom.primeton.juxtapose.rule.example;
importjava.io.IOException;
importorg.drools.DroolsException;
importorg.drools.IntegrationException;
importorg.drools.RuleBase;
importorg.drools.WorkingMemory;
importorg.drools.event.DebugWorkingMemoryEventListener;
importorg.drools.io.RuleBaseLoader;
importorg.drools.spi.Activation;
importorg.drools.spi.AgendaFilter;
importorg.xml.sax.SAXException;
/**
*一个简单的业务逻辑层,用来模拟商业逻辑。
*
*@authorliuxiang
*
*/
publicclassBusinessLogicLayer{
privatestaticfinalStringBUSINESS_RULE_FILE="BusinessRulesStudent.drl";
privatestaticRuleBasebusinessRules=null;
//设置过滤条件,名称为"FemaleSchoole"的规则将不会被执行。
privatestaticAgendaFilterfilter=newAgendaFilter(){
publicbooleanaccept(Activationactivation){
if(activation.getRule().getName().equals("Stude")){
returnfalse;
}
returntrue;
}
};
/**
*如果还没有装载商务规则的话就装载它。
*@throwsIOException
*@throwsSAXException
*@throwsIntegrationException
*@抛出异常-通常从这里恢复
*/
privatestaticvoidloadRules()throwsIntegrationException,SAXException,IOException{
if(businessRules==null){
businessRules=RuleBaseLoader.loadFromUrl(com.primeton.juxtapose.rule.example.BusinessLogicLayer.class.getResource(BUSINESS_RULE_FILE));
}
}
/**
*评价学生是否能够入学
*@paramstockToBuy
*@throwsException
*/
publicstaticvoidevaluateStudentRecommend(Studentstudent)throwsException{
loadRules();
System.out.println("FIREAllRULES");
System.out.println("------------------------------------------------------------");
WorkingMemoryworkingMemory=businessRules.newWorkingMemory();
workingMemory.addEventListener(newDebugWorkingMemoryEventListener());
workingMemory.assertObject(student);
workingMemory.fireAllRules(filter);
}
/**
*测试用例
*测试学生juxtapose就读USST学校是否符合条件
*@paramargs
*@throwsException
*/
publicstaticvoidmain(String[]args)throwsException{
//BusinessLayerbusinessLayer=newBusinessLayer();
Studentstudent=newStudent();
student.setSchoole("USST");
student.setStudentName("juxtapose");
student.setStudentAge(20);
student.setStudentSex("Male");
BusinessLogicLayer.evaluateStudentRecommend(student);
}
}
3。
在该类的运行时需要用到规则的定义,采用XML的方式来描述商务逻辑中用到的各种规则。
规则文件BusinessRulesStudent.drl的定义如下:
xmlversion="1.0"?
>
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/rulesrules.xsd http: //drools.org/semantics/javajava.xsd"> import>java.lang.Object import> import>java.lang.String import> import>com.primeton.juxtapose.rule.example.Student import> functions> publicstaticvoidprintStudent(com.primeton.juxtapose.rule.example.Studentstudent){ System.out.println("StudentName: "+student.getStudentName() +"nSudentAge: "+student.getStudentAge() +"nStudentSex: "+student.getStudentSex() +"nRecommend"+student.getStudentName() +"togotoschoole" +student.getSchoole() +": " +student.getRecommend()); } functions> condition>student.getSchoole().equals("USST") condition> -- condition>student.getRecommend()==null condition>--> condition>student.getStudentAge()>15 condition> --Whathappenswhenthebusinessruleisactivated--> consequence> student.setRecommend(Student.YES); printStudent(student); consequence> condition>student.getSchoole().equals("FUDAN") condition> -- condition>student.getRecommend()==null condition>--> condition>student.getStudentAge()>18 condition> --Whathappenswhenthebusinessruleisactivated--> consequence> student.setRecommend(Student.YES); printStudent(student); consequence> 在该规则文件中共设置了两个规则,其规则名分别为USSTSchoole、FUDANSchoole,前者用于执行就读USST学校的规则设置,其条件为: 就读学校为USST,学生年龄大于15岁,推荐就读变量为null;后者FUDANSchoole规则用于执行就读FUDAN学校的规则设置,其条件为: 就读学校为FUDAN,学生年龄大于8岁,推荐就读变量为null; 4。 利用Junit进行测试。 测试类BusinessLogicLayerTest.java包含两个测试方法,分别用于执行就读USST和FUDAN学校的测试。 packagecom.primeton.juxtapose.rule.example; importjunit.framework.TestCase; /** *商务逻辑的单元测试, *用于检测我们的业务规则是否得到了正确的执行。 * *@authorliuxiang * */ publicclassBusinessLogicLayerTestextendsTestCase{ /** *测试学生juxtapose就读USST学校是否符合条件 *@throwsException */ publicvoidtestGotoUSST()throwsException{ //创建一个学生实例,目标就读学校为USST Studentstudent=newStudent(); student.setSchoole("USST"); student.setStudentName("juxtapose"); student.setStudentAge(16); student.setStudentSex("Male"); //运行规则 BusinessLogicLayer.evaluateStudentRecommend(student); //测试该学生能够入学符合规则中设定的条件 //assertTrue(student.getRecommend()! =null); assertTrue("YES".equals(student.getRecommend())); } publicvoidtestGotoFUDAN()throwsException{ //创建一个学生实例,目标就读学校为USST Studentstudent=newStudent(); student.setSchoole("FUDAN"); student.setStudentName("jxta"); student.setStudentAge(20); student.setStudentSex("Male"); //运行规则 BusinessLogicLayer.evaluateStudentRecom
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 规则 引擎 Drools 简明 教程
