论坛首页 Java企业应用论坛

规则引擎实现探讨

浏览 43852 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-09-29  
有没有可能直接用ruby DSL来定义规则呢?是不是更简单?还可以在Java平台上面用JRuby来跑。

仅仅一猜想,因为不了解规则引擎。
0 请登录后投票
   发表时间:2006-09-29  
robbin 写道
有没有可能直接用ruby DSL来定义规则呢?是不是更简单?还可以在Java平台上面用JRuby来跑。

仅仅一猜想,因为不了解规则引擎。


是的,如果使用在一个比较窄范围内,比如楼主的示例,仅仅针对一个有限的情况,规则间不会互相影响,可能用Ruby DSL搞一个更快。
0 请登录后投票
   发表时间:2006-09-29  
引用

-record(customer, {name,credicard,gender,points})
-record(order,{customer,amount,item,catalog}).

points(#order{customer=#customer{points=Points}}=Order)->
    gift(points(Order,Points)).
points(#order{amount=Amount,customer=#customer{credicard=true}},Points)->
    Amount+Points;
points(#order{catalog=car,amount=Amount,customer=#customer{credicard=true}},Points)->
       Points+Amount/100*6;
points(#order{catalog=estate,amount=Amount,customer=#customer{credicard=true}},Points)->
   Points+Amount/100*8;
points(Order,Points)->
       Points.

 
gift(Points)when 100=<Points,Points=<300->{Points-150,gift150};
gift(Points)when 300<Points,Points=<500->{Points-300,gift300};
gift(Points)when Points>500->{Points-400,gift400}; 
0 请登录后投票
   发表时间:2006-10-04  
以前用beanshell做过类似的事情,规则定好,用java语法写规则,虽然繁索一点,但是学习曲线很低,而且不用实现引擎。
0 请登录后投票
   发表时间:2006-10-04  
jxb8901 写道


1、如何定义规则?
一般规则引擎中定义规则的方式如下:

if {
	规则
}
then {
	动作
}


但这样的规则“消费1元人民币积1分”使用if...then...该如何定义呢?好象没法定义。

另外感觉这类规则定义就是一系列的if...then...这其中的逻辑和我们在java中的逻辑没有什么区别,
只是换了一种形式而已。这样的规则根本没办法给业务人员使用。



"消费一元人民币积一分"的处理比较直观的处理方法就是把用户的积分信息当作一个类放入workingmemroy。消费的时候直接对积分信息里面的相关属性进行操作。
drools规则引擎的表达式更像java逻辑里面的switch...case...(if...else...是互斥组的一个表现形式),带来的好处就是优先级变动或是组变动的时候不会对代码产生大的影响。同时可以很方便的在不同的规则组之间进行跳转,有点goto的感觉。在处理复杂和繁琐的逻辑的时候提供了比java代码更好的可读性。如果有必要让业务人员参与到规则的定义的话,可以预先定义相应的DSL。
这里再补充一个好处,就是可以让你所关心的业务逻辑统一集中。比如我接触到的一个项目原先是使用sp实现的,而每个分公司sp都有可能更改,后续的维护人员往往一个修改就要阅读所有的sp。而使用业务规则定义可以方便集中管理,节省大量人工。

jxb8901 写道

2、如何处理数据库与规则引擎的关系?
再者规则引擎是基于事实进行推演,所以在触发规则引擎计算之前,需要先装入事实。基于JSR94的实现
多使用OO的方式,例如:
loadRules(); // 装入规则
WorkingMemory workingMemory = businessRules.newWorkingMemory();
workingMemory.addEventListener(new DebugWorkingMemoryEventListener());
workingMemory.assertObject(student); // 装入事实
workingMemory.fireAllRules(filter); // 触发计算

摘自http://www.blogchinese.com/06042/201878/archives/2006/200652418217.shtml

这里就有一个问题,如果我的事实是基于数据库记录,那么该如何装入事实?因为规则的定义中条件部分
一般是基于对象的属性,动作部分一般是基于对象的方法,所以如果事实能使用数据记录,那么条件特别是
动作该如何定义?



我使用hibernate在service层一次性把相关记录load进memory,在规则引擎里面进行运算的事实大多是PO,运算结束后flush一下就可以了。在规则引擎中的方法是纯粹的内存数据的操作,不涉及数据库。

jxb8901 写道

3、需要Rete算法吗?
只要对规则引擎稍有接触,应该都听说过“Rete算法”,现有的商业或开源的规则引擎多是基于该算法。多数会解决
这样一个问题,就是自动处理动作对事实的反馈,如果一个动作影响了事实,那么会重新针对事实过滤规则,我想这样的反馈
计算可能大大影响了规则引擎的性能,而正Rete算法解决了规则引擎的性能问题。但上述规则并不需要这样的特性,所以性能问题不会表现在这些方面。

因为对这类商业和开源的规则只是有一个泛泛的了解,不知其能否解决这些问题?怎样解决这些问题?


我测试的情况而言,规则引擎的性能是可以接受的,就如我上面说的hibernate+drools的组合,性能瓶颈无论如何是不会出现在规则引擎这里的。没有在规则组之间频繁跳动的情况下性能甚至优于纯java代码。
0 请登录后投票
   发表时间:2006-10-10  
Trustno1 写道
引用

-record(customer, {name,credicard,gender,points})
-record(order,{customer,amount,item,catalog}).

points(#order{customer=#customer{points=Points}}=Order)->
    gift(points(Order,Points)).
points(#order{amount=Amount,customer=#customer{credicard=true}},Points)->
    Amount+Points;
points(#order{catalog=car,amount=Amount,customer=#customer{credicard=true}},Points)->
       Points+Amount/100*6;
points(#order{catalog=estate,amount=Amount,customer=#customer{credicard=true}},Points)->
   Points+Amount/100*8;
points(Order,Points)->
       Points.

 
gift(Points)when 100=<Points,Points=<300->{Points-150,gift150};
gift(Points)when 300<Points,Points=<500->{Points-300,gift300};
gift(Points)when Points>500->{Points-400,gift400}; 


高手顺手就 ErLang 了一个啊。

感觉FP的东西写这种rule似乎很自然。
0 请登录后投票
   发表时间:2006-10-10  
plz pay attention to Chordiant Rule Server
0 请登录后投票
   发表时间:2006-10-11  
江南白衣 写道
robbin 写道
有没有可能直接用ruby DSL来定义规则呢?是不是更简单?还可以在Java平台上面用JRuby来跑。

仅仅一猜想,因为不了解规则引擎。


是的,如果使用在一个比较窄范围内,比如楼主的示例,仅仅针对一个有限的情况,规则间不会互相影响,可能用Ruby DSL搞一个更快。

规则间是否相互影响好象的确是一个影响决策的重要因素!
0 请登录后投票
   发表时间:2006-10-11  
江南白衣 写道
我觉得jboss rules的mapping式DSL胜在够简单,完全平民级的东西,比自己javacc,antlr容易多了。

同意,JBoss Rules的DSL虽然使用有一定局限性,但实现方式确实不错,使用简单的方式达到了很好的效果。

江南白衣 写道

这个语法,在实际应用中,把相关规则集中定义和管理后,加上rete算法,还是比写在代码里好一点的。特别如果规则之间会关联,会互相影响的情况。

drools->jboss rules 不仅是改个名字,2.0用的是XML语法,DSL更是恶梦(自己写XML节点分析器),而3.0的语法已经有点像ilog,DSL也换了这种平民级的Mapping,另外还提供了Eclipse Plugins的IDE,保证客户写DSL的时候不容易写错。

dada 写道

drools规则引擎的表达式更像java逻辑里面的switch...case...(if...else...是互斥组的一个表现形式),带来的好处就是优先级变动或是组变动的时候不会对代码产生大的影响。同时可以很方便的在不同的规则组之间进行跳转,有点goto的感觉。在处理复杂和繁琐的逻辑的时候提供了比java代码更好的可读性。如果有必要让业务人员参与到规则的定义的话,可以预先定义相应的DSL。
这里再补充一个好处,就是可以让你所关心的业务逻辑统一集中。比如我接触到的一个项目原先是使用sp实现的,而每个分公司sp都有可能更改,后续的维护人员往往一个修改就要阅读所有的sp。而使用业务规则定义可以方便集中管理,节省大量人工。


现在对JBoss Rules的兴趣更大了!
看来JBoss Rules的在实际项目中的应用还是蛮多的啊,要是能发起对其实际应用的讨论就好了
0 请登录后投票
   发表时间:2006-10-11  
dada 写道
我使用hibernate在service层一次性把相关记录load进memory,在规则引擎里面进行运算的事实大多是PO,运算结束后flush一下就可以了。在规则引擎中的方法是纯粹的内存数据的操作,不涉及数据库。

如果是实时的交易处理,实际在规则引擎的working memory中只会有少量的对象,这种hibernate与drools结合的使用方式应该还是很好的。
但如果使用批处理的方式进行处理,那在记录数很多的情况下(比如一天的交易记录可能有几十万条),这种方式不知会不会影响规则引擎的计算?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics