java

位置:IT落伍者 >> java >> 浏览文章

在你的企业级java应用中使用Drools(图)


发布日期:2024年06月27日
 
在你的企业级java应用中使用Drools(图)

什么是Drools

Drools 是一个基于Charles Forgys的Rete算法的专为Java语言所设计的规则引擎Rete算法应用于面向对象的接口将使基于商业对象的商业规则的表达更为自然Drools是用Java写的但能同时运行在Java和Net上

Drools

Drools 被设计为可插入式的语言实现目前规则能用Java Python和Groovy实现更为重要的是Drools提供了声明式程序设计(Declarative Programming)并且使用域描述语言(Domain Specific Languages (DSL))-专为你的问题域定义了某种模式的Xml 它已经足够灵活到可以用来描述你的问题域DSLs包含的XML元素(Element)和属性(Attribute)代表了问题域中各种要素

这段时间企业级Java简直能让你睡着有多少JEEEJB应用程序只是从网页提取数据并把它们存入到数据库中?但开发者真正应该开发和维护的却是他们应用程序中复杂的商业逻辑这个问题不仅仅适用于将要新应用而且渐渐地也适用于那些长期运行的商业核心应用它们的内部逻辑也需要经常改变而且往往要求在一个非常短的时间内

在以前的文章中用Drools让你的商业逻辑使用框架我介绍了Drools框架展示了它如何用来组织复杂的商业逻辑Drool用一组简单的众所周知的事物替换了许多缠杂的if…then表达式如果你经历过和商业客户的会议并为他们提出的想要实现的东西的复杂程度搞得头痛或许你应该考虑一下像Drools这样的规则引擎了这篇文章将向你展示如何在企业级Java应用中使用Drools

一路到底的框架

大多数开发者都有自己喜爱的框架无特定顺序它们包括表现层框架(Struts JSF Cocoon和Spring)持久化框架(JDO Hibernate Cayenne and Entity Beans)以及结构框架(EJB 又是Spring Pico和Excalibur) 还有其它很多每种框架都各有所长给开发者提供子许多即开即用的功能使用框架来部署应用意味着你避免了许多让人厌烦的细节让你集中注意力到关键之处

到目前为直在框架所能做的事中仍然有一个缺口那就是商业逻辑没有框架像EJB和Spring这样的工具虽好但它们却几乎没有提及怎么组织你的那些if …then语句把Drools加到你的开发工具箱中意味着现在你可以一路到底的使用框架来构建你的应用程序显示了这样的一个应用

  

用于Java应用的框架

这篇文章将基于我们已经了解的Drools框架的功能这些功能可以让我们构建这样的一个应用]

我什么时候应该使用规则引擎?

如果你有一把锤子那所有的东西都看起来都像钉子这句话在软件工程领域几乎成了陈词滥调了虽然规则引擎能解决我们的许多问题但确实值得认真考虑一下规则引擎对我们的企业级Java应用是否合适需要问的问题有

● 我的应用程序有多复杂?对于那些只是把数据从数据库中传入传出并不做更多事情的应用程序最好不要使用规则引擎但是当在Java中有一定量的商业逻辑处理的话可以考虑Drools的使用这是因为很多应用随着时间的推移越来越复杂而Drools可以让你轻松应对这一切

● 我的应用的生命周期有多久?这个问题的正确答案往往是令人惊讶的长――还记得那些认为他们的程序不会苟活到年的大型机的程序员吗?使用规则引擎将会在中长期得到好处像这篇文章所展示的那样甚至原型都能从Drools与灵活方法的组合中获益原型系统转化成生产系统

● 我的应用需要改变吗?唯一能确定的是你的需求将会改变无论是在开发过程中或是在开发完成以后Drools使用一个或多个简单易配的XML文件帮你来应对这一切

那么性能呢?

如果你正在写一个企业级应用很有可能它会扩展到成百(如果不是成千)的用户你已经知道现有的Java和JEE应用能做到这一点但一个使用了Drools的应用对这一压力的表现如何?答案是令人吃惊的好大多数开发者只是因为不愿失控而依赖于他人的代码(比如某种框架)想想这个Drools不仅可以让你的应用和传统的编程方法一样快甚至可以更快看下面

● 避免糟糕的代码Drools引导开发者去做正确的事你可以确定你正在写的代码是好的但你的开发伙伴呢?你可以同样这样说吗?使用框架可以让你更轻松地写出更快更好的代码

● 优化过的框架你有多少次看见商业逻辑重复地从数据库中提取相同的信息从而降低了整个应用的速度?如果正确使用的话Drools不仅仅能够记住信息而且还能记住以往使用该信息进行测试的结果从而大幅提升应用的速度

● Rete算法很多次我们并不是真正需要使用if条件被Drools实现的Rete算法可以用一个优化的方法替换掉所有的if…then表达式需要重点提及的是Rete算法在使用更多的内存来降低运行时延迟方面作了折衷当然这在现代的应用服务器中并不是一个问题我们也并不推荐你在移动手机上使用Drools!

我们到哪里了?

在我们上一篇文章中我们写了一个基于Drools引擎的简单的股票交易程序我们实现了不同的商业规则展示了我们可以如何迅速地改变规则去适应商业需求并且JUnit测试给了我们高度自信可以确认系统确实是像我们设想的那样运作的但是这个应用几乎没有用户介面而且用硬编码代替了数据库为了把我们的程序提升到企业级的水平我们需要增加两个主要的东西

● 某种用户介面最理想的是基于标准的Web表现层的框架

● 一个数据存取对象(DAO)让Drools与数据库(或其它后端)交互

从现有表现框架中实现规则引擎

大多数企业级Java应用是通过Web介面进行交互的其中最被广泛使用的Web表现层框架是Apache的Struts理想的结果是我们写的应用可以从表现层知道它下面的应用层而不是通过相反的方向它的好处在于不仅仅可以使我们将来变换其它的表现层(比如Ajax或web service界面)而且意味着示例代码可以非常容易地应用于其它像Spring的框架

下面的代码片断演示了始何从Web表现层调用商业逻辑(通过规则引擎)并根据返回结果显示不同的页面这一例子中我们使用了一个Struts行为但其代码是和使用其它表现层框架甚至一个Servlet或一个Jsp页面是很类似的这个片断使用了strutsconfigxml配置文件JSP页面来上传/显示数据并且生成WAR文件来进行布署片断展示了怎样把规则引擎和web框架集成使用

import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import orgapachestrutsactionAction;import orgapachestrutsactionActionForm;import orgapachestrutsactionActionForward;import orgapachestrutsactionActionMapping;import BusinessLayer;/** * Sample Struts action with Pseudocode * 使用伪代码的Struts行为示例 */public class SampleStrutsAction extends Action{ /** * Standard Struts doPerfom method* 标准的Struts doPerform方法 */public ActionForward doPerform(

ActionMapping mapping

ActionForm form

HttpServletRequest request

HttpServletResponse response)

throws InvalidEntryPointException {//Local Variables//本地变量

StockOffer userOffer =null;

//Get any previous values from the session//从session取得以前的数据

userOffer=(StockOffer)requestgetSession()

getAttribute(PREVIOUS_STOCK_OFFER);

//create this object if it is null//如为null则创建新对象

if (null==userOffer){

userOffer = new StockOffer();

}//Update with the incoming values //用上送的数据更新//These values match those on the form

//这些数据是与form中的数据相对应的

userOffersetStockName(request

getParameterValue(STOCK_NAME));

userOffersetStockPrice(request

getParameterValue(STOCK_PRICE));

userOffersetStockQuantity(request

getParameterValue(STOCK_QTY));

//Reset the output value//重置输出数据

userOffersetRecommendPurchase(null);//Call the Business Layer//调用商业层

BusinessLayerevaluateStockPurchase(userOffer);

//Forward to the appropriate page //转向合适的页面

if (YESequals(

testOffergetRecommendPurchase()){

return mappingfindForward(YES_WEB_PAGE);

} //otherwise default to the no page//否则指向无此页面

return mappingfindForward(NO_WEB_PAGE);}}

这个例子包含了几个东西经常我们需要的数据是用户通过好几个网页传来的因此在这一例子中展示了通过session中的StockOffer对象来保存过去以来的数据

下一步如果用户改变了一些值我们更新StockOffer对象然后我们重置了rcommendPurchase标志用以在调用商业逻辑层之前清除以前的结果最后我们使用商业逻辑层的返回来决定让用户转向哪一页面

在这一例子中需要注意我们将商业逻辑(买或不买一支股票)与表现层逻辑(决定转向哪一页面)分离开来这将使我们可以在不同的应用中重用我们的商               

上一篇:Java线程:新特征-信号量

下一篇:java获取系统时间