guangnian0412's BLOG

Java in my life

常用链接

统计

积分与排名

我关注的Blog

最新评论

JBoss Rules 学习(三): Drools规则引擎 (上)

从今天开始,我们将分两期来详细的介绍Drools规则引擎的原理,和各关键类的使用方法。

Drools 规则引擎(上)

1. 概述 :
Drools 分为两个主要部分:构建( Authoring )和运行时( Runtime )。

构建的过程涉及到 .drl 或 .xml 规则文件的创建,它们被读入一个解析器,使用 ANTLR 3 语法进行解析。解析器对语法进行正确性的检查,然后产生一种中间结构“ descr ”, descr 用 AST 来描述规则。 AST 然后被传到 PackageBuilder ,由 PackagBuilder 来产生 Packaged 对象。 PackageBuilder 还承担着一些代码产生和编译的工作,这些对于产生 Package 对象都时必需的。 Package
对象是一个可以配置的,可序列化的,由一个或多个规则组成的对象。下图阐明了上述过程:
 
Figure 1.1
Authoring Components

RuleBase 是一个运行时组件,它包含了一个或多个 Package 对象。可以在任何时刻将一个 Package 对象加入或移出 RuleBase 对象。一个 RuleBase 对象可以在任意时刻实例化一个或多个 WorkingMemory 对象,在它的内部保持对这些 WorkingMemory 的弱引用。 WorkingMemory 由一系列子组件组成。当应用程序中的对象被 assert 进 WorkingMemory ,可能会导致一个或多个 Activation 的产生,然后由 Agenda 负责安排这些 Activation 的执行。下图说明了上述过程:

 
Figure 1.2 . Runtime Components

2.构建(Authoring):

主要有三个类用来完成构建过程:DrlParser, XmlParser 和 PackageBuilder。两个解析器类从传入的Reader实例产生descr AST模型。PackageBuilder提供了简便的API,使你可以忽略那两个类的存在。这两个简单的方法是:“addPackageFromDrl”和“addPackageFromXml”,两个都只要传入一个Reader实例作为参数。下面的例子说明了如何从classpath中的xml和drl文件创建一个Package对象。注意:所有传入同一个PackageBuilder实例的规则源,都必须是在相同的package 命名空间(namespace)中。

PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( 
new InputStreamReader( getClass().getResourceAsStream( "package1.drl" ) ) );
builder.addPackageFromXml( 
new InputStreamReader( getClass().getResourceAsStream( "package2.drl" ) ) );
Package pkg 
= builder.getPackage();


Figure 2.1 PackageBuilder

PackageBuilder是可以配置的,使用PackageBuilderConfiguration。通常,你可以指定另一个parent ClassLoader和用什么编译器(compiler),默认是Eclipse JDT。下面显示了如何指定JANINO编译器:

PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
conf.setCompiler( PackageBuilderConfiguration.JANINO );
PackageBuilder builder 
= new PackageBuilder( conf );

Figure 2.2 . PackageBuilderConfiguration

3
.RuleBase:

Figure 3.1 . RuleBase

一个RuleBase包含了多个将被使用的规则包(packages of rules)。一个RuleBase是可以序列化的,所以它可以被配置到JNDI或其他类似的服务。通常,第一次使用时,一个RuleBase被创建并缓存。RuleBase用RuleBaseFactory来实例化,默认返回一个ReteOO RuleBase。可以传入参数来指定采用ReteOO或Leaps。然后,用addPackage方法加入Package实例。你可以加入有相同命名空间(namespace)的多个Package。

RuleBase ruleBase  = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);

Figure 3.2. RuleBaseFactory

一个 rulebase instance 是线程安全的,所有你可以在你的应用中,让一个 rulebase instance 在多个线程中共享。对于一个 rulebase 的最通常的操作是产生一个新的 WorkingMemory 。

这个 rulebase 保持着到它所产生的 WorkingMemoryd 的弱引用,所以在长时间运行的 WorkingMemory 中,如果 rules 发生改变,这些 WorkingMemory 可以即使的根据最新的 rules 进行更新,而不必重启 WorkingMemory 。你也可以指定 RuleBase 不必保持一个弱引用,但是你要保证 RuleBase 不用更新。

ruleBase.newWorkingMemory();   //  maintains a weak reference.
ruleBase.newWorkingMemory(  false  );  //  do not maintain a weak reference

任何时候, Package 可以被加入或移除;所有的改变都会被反映到现存的 WorkingMemory 中。不要忘了调用 fireAllRules() 让 Activations 激发。

ruleBase.addPackage( pkg  );   //  Add a package instance
ruleBase.removePackage(  " org.com.sample "   );   //  remove a package, and all its parts, by it's namespace
ruleBase.removeRule(  " org.com.sample " ,  " my rule "  );  //  remove a specific rule from a namespace

虽然有删除一个单独规则的方法,但是却没有加入一个单独规则的方法(要达到这个目的只有加入一个只有一条规则的 package )。

RuleBaseConfigurator 可以指定 RuleBase 的附加行为。在加入 RuleBase 后, RuleBaseConfiguration 就变成不可变对象。

RuleBaseConfiguration conf  =   new  RuleBaseConfiguration();

conf.setProperty( RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
                  RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY );

RuleBase ruleBase 
=   new  ReteooRuleBase( conf );

两个主要的属性是: PROPERT_ASSERT_BEHAVIOR 和 PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR (在以后的部分中会解释)。所有的属性值都是 RuleBaseConfiguration 类中的静态域常量。


Figure 3.3 RuleBaseConfiguration



posted on 2006-06-04 12:50 guangnian 阅读(23253) 评论(14)  编辑  收藏 所属分类: JBoss Rules(Drools)

评论

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2006-06-08 00:02 steeven

好文,谢谢~

偶一直在想什么场合下需要rule engine.
1. 如果逻辑在开发前就定好,虽然比较复杂,如果用rule engine,碰到重构,rule要手工操作。而且规则语法的错误不容易检查出来。
2. 如果要客户来写规则,让客户学习语法规则还是用界面生成呢?
  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2006-06-08 15:00 guangnian

@steeven
我想rule engine主要用在规则经常变化的情况在,此时只需要改动drl文件,而不需要改代码。对于规则语法错误可以靠IDE工具来写规则啊,JBoss已经有提供Eclipse plugin了。
规则当然是程序员根据客户的需求来写的啊  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2006-11-22 18:09 syyhpf

那测试呢?修改完规则后怎样测试?在运行系统中?  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2006-11-30 14:55 coolfish

应该有专门的测试环境吧  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2007-07-04 13:30 liujg

所有传入同一个PackageBuilder实例的规则源,都必须是在相同的package 命名空间(namespace)中.请问这里的package的命名空间是什么呢?  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2007-07-04 13:38 liujg

看来今年没有人关注该贴了!郁闷......  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上)[未登录] 2007-08-23 12:48 dd

好文章啊,要是能给个具体的操作就好了..举个例子就好了.我看的很迷糊  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上)[未登录] 2007-08-27 09:29 sclsch

mark  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2007-11-24 15:32 myim

我给个例子:
电梯行业,

如果楼层高是10层
那么控制板上的按钮就是10+5(其它功能)个
如果载重1000公斤
那么就选择A型号的电机
如果是前后开门
那么加工路线就是R
如果门是对开
那么就选择Item Number D作为这个合同的门类型来加工
如果客户要喷涂蓝色的门
那么就选择喷涂加工路线,
并且喷涂颜料选择Item Number Blue
。。。。

类似的Rule可以达到几万条以上,不知道这个企业作用是否适合选择DRools来做,真实地ERP中也使用Rule来做的。

请问DRools在这样的场景中是否物有所值?还是说DRools用在这样的地方,大材小用了,他有更高级的用处?

刚刚发现DRools, 非常有兴趣研究
  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2008-01-18 14:16 ePim

路过,今天开始接触这个东本,好难入门啊~~  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2009-02-10 15:16 hc

这个版本低了 很多属性字段都不适用了   回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上) 2010-02-03 17:30 ddoo

http://www.jboss.org/drools/documentation.html

这上面有更详细的文档.  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上)[未登录] 2011-03-05 23:01 xiaogang

请问文中所说的 descr AST中间结构是一种什么样的结构啊?在网上搜不到相关资料,谢谢  回复  更多评论   

# re: JBoss Rules 学习(三): Drools规则引擎 (上)[未登录] 2014-03-21 14:19 Lee

也就是说我可以用antlr把自己的规则语法映射到drools可是别的程度 so good  回复  更多评论