锁定老帖子 主题:规则引擎
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-09-26
关于rule definition, 用rule engine去检查rule & fact matching和rule priority的办法, 理论上比较先进, 但实际操作起来对实施者的要求比较高,
用脚本来做rule definition也是个比较好的办法, 比如很有名的游戏robocode, 就是采用着个办法。 我们做过有个项目里面有比较复杂的规则, 一开始也是打算用rule engine, 当时看的是ofbiz, 后来可能是水平不够吧, 有些rule在ofbiz里不知道如何实现。 后来就借荐robocode的方法, 定义一堆API, 用脚本调用API的方法来定义rule, 当脚本和API比较成熟以后, 写tools来生成动态脚本, 这样用户就可以用tools来定义rule了。这个系统用户现在用的很不错。 |
|
返回顶楼 | |
发表时间:2004-09-26
谢谢 gigix potian yyhong
俺受益匪浅。以前一直不是很注意这个咚咚,偶尔过目也是认为是简单的局限性很强的应用而已,现在看来,至少在我以后实施的项目中会考虑这正方法的可行性。 potian举的那个例子也很详细,不过我感觉还有一些定义的信息并不是很明确,f1,f2规则,和事实1 事实2。他们匹配的顺序是怎样定义的呢?我认为匹配规则大概有这两种方式: 1)是由规则集开始遍历事实集的 2)以事实集开始遍历规则集 伪代码如下: 1) for( everyRule in {f1,f2});{ for(everyfact in {fact1,fact2,..});{ if(everyRule.matching(everyfact);); modify(everyRule,everyfact);; } } 2); for( everyFact in {fact1,fact2});{ for(everyrule in {rule1,rule2,..});{ if(everyfact.matching(everyrule);); modify(everyRule,everyfact);; } } 规则集的引入带来的好处实在太大,特别是对于业务规则易变的应用来说,它的作用不同凡响。 potian,我更关心它在类似OA这样的工作流中作用如何?以及多阶段交易流程为主的银行/商务应用中它引入的可扩展性如何? |
|
返回顶楼 | |
发表时间:2004-09-26
很高兴看到这个讨论,也正打算了解规则引擎,gigix要快点把文章写出来
|
|
返回顶楼 | |
发表时间:2004-09-26
hehe,首先我声明偶不懂那个规则引擎。只是很多年前对那类产生式系统有点印象。给我的感觉,能够应用的规则系统都是理论上非常简单的那一类,比如说一般不会引入时间因素,也不能提供较为完善的基于上下文的推理,而且推理机一般也只是实现了命题逻辑概念下的搜索匹配(谓词逻辑的推理机稍微复杂一些的问题就会慢得要死,就像那个prolog),一般也都基于封闭世界假设。
我不知道现在讨论的这个规则引擎是不是这一类。如果是的话,我觉得这类规则系统能够解决的问题是有限的,关键在于这个范围在哪里。 |
|
返回顶楼 | |
发表时间:2004-09-26
大概我在96-97年开始关注规则的问题,那个时候我还没有什么明显的开发方法的概念.即使到今天我对这个问题的研究也没有太多的答案,而是由太多太多的问题.既然大家讨论规则引擎,我就顺便把我对规则问题的思考和疑问介绍给大家.
首先明显的一点,使用规则会对你的需求了解的过程,造成深刻而无法预料的影响.因为使用了规则,所以你的程序中表达的业务就可以划分为业务数据对象和业务规则两个部分.需求分析阶段了解的主要部分则有传统的对于对于需求的全范围的建模变成对需求中的业务所表达的数据进行建模.而对于业务规则的建模在向后推延到实施阶段。 其次业务规则的定义将会给需求分析的方法带来根本性的改变。由于业务规则将成为一种可以动态调整的部分,从而在初期将这些部分从需求在程序中固化下来的部分进行区分就是完全必要的。而这些区分的原则将非常重要,并且也会非常微妙。这里我们可以分析一下前面那个例子: 引用 开车”的规则有说“如果绿灯亮,前进”,也有说“如果前方有人,停车”,那么既有绿灯又有行人时该怎么办呢?你就必须指定第二条规则优先级高。但这些都是在规则里面定义好的,你不应该在运行时干预规则引擎。
在这个例子中判断绿灯亮、前进、判断前方有人、停止、问候前方人的母亲,这些都是规则,但是这些部分基本不会发生变化,所以应该固化在程序内部。而实际上进一步,前方有人-停止和前方绿灯-前进,这两个规则也是基本不会被更改的,也是需要固化的。但是这种逻辑实际上还是有可能在某些情况下被更改的,这就需要对这些规则留下动态屏蔽的能力。而实际上经常进行改变的,是对于前面绿灯-前进和前面有人-停止,这两个规则优先次序的判断逻辑,这个部分无疑是应该完全用规则引擎来管理。然而实际应用的情况要复杂的多,比如一张订单可以包括10个货物栏。这个时候,首先我们要明确知道这个规定注定会影响数据的存储逻辑,而数据的存储逻辑实际上是应该放在数据访问层中的。下订单这个业务行为也非常难与定义为一种业务逻辑还是一种行为职责,也就是产生订单这个行为是用一个程序的动作去实现,还是用一个规则引擎的规则实现?当然你可以先使用一个程序的动作实现,然后确定一个屏蔽的方法调用。而实际上我们遇到的情况将比这个复杂的多,需要你作出非常多的权衡。而实际上确实存在这样的一种可能,也就是你的程序的业务层中将不会再有具体的业务行为的业务对象,而只是一些单纯的数据对象和一些的方法对象,而这两者之间的联系仅仅依靠规则引擎来连接。而我认为在这样的情况下kiss将是必须遵守的。
所以第一个问题的答案是:你不应该自己选择。如果你要自己选择,那不就回到了原来的做法、在程序里写一大堆if...else...吗?那还要规则引擎来干什么呢?还是用上面这个例子,你可以再加上一条规则:“如果(绿灯亮 并且 前方有人),问候车前行人的母亲”。 而实际上对于需求分析的影响将是使用规则引擎造成的一个最为值得关注的问题,需要使用更加新鲜的分析方法。原来的基于数据和过程的认识系统,必须将过程和过程中的逻辑判断区分开来,并且进一步将逻辑判断划分为规则和流程所自身私有的规则加以区分。实际上这就意味着工作流引擎应该和规则引擎互相的可以调用,也就是说在每一个流程的节点都可以植入一个规则引擎的接口。(而实际上我认为是有AOP来设计一种规则和流程公用的引擎将是一种思路。) 同时由于规则引擎的引入,将会给测试造成的影响也是非常多,这一点大家应该比较好理解。实际全面的应用规则引擎将给你的日记开发的全过程造成非常重要的影响,而首先要解决的问题就是你必须决定要把什么东西放到规则引擎去完成,基本上可以认为一个项目的成功与否在这样的情况下关键就在此。 |
|
返回顶楼 | |
发表时间:2004-09-26
potian 写道 不用找文章了,规则引擎的理论基础就是专家系统,国内很早就翻译了一本非常经典的专家系统书 推荐一下, 书叫什么名字。 谢谢。 |
|
返回顶楼 | |
发表时间:2004-09-26
ozzzzzz 写道 大概我在96-97年开始关注规则的问题,那个时候我还没有什么明显的开发方法的概念.即使到今天我对这个问题的研究也没有太多的答案,而是由太多太多的问题.既然大家讨论规则引擎,我就顺便把我对规则问题的思考和疑问介绍给大家.
首先明显的一点,使用规则会对你的需求了解的过程,造成深刻而无法预料的影响.因为使用了规则,所以你的程序中表达的业务就可以划分为业务数据对象和业务规则两个部分.需求分析阶段了解的主要部分则有传统的对于对于需求的全范围的建模变成对需求中的业务所表达的数据进行建模.而对于业务规则的建模在向后推延到实施阶段。 其次业务规则的定义将会给需求分析的方法带来根本性的改变。由于业务规则将成为一种可以动态调整的部分,从而在初期将这些部分从需求在程序中固化下来的部分进行区分就是完全必要的。而这些区分的原则将非常重要,并且也会非常微妙。这里我们可以分析一下前面那个例子: 引用 开车”的规则有说“如果绿灯亮,前进”,也有说“如果前方有人,停车”,那么既有绿灯又有行人时该怎么办呢?你就必须指定第二条规则优先级高。但这些都是在规则里面定义好的,你不应该在运行时干预规则引擎。
在这个例子中判断绿灯亮、前进、判断前方有人、停止、问候前方人的母亲,这些都是规则,但是这些部分基本不会发生变化,所以应该固化在程序内部。而实际上进一步,前方有人-停止和前方绿灯-前进,这两个规则也是基本不会被更改的,也是需要固化的。但是这种逻辑实际上还是有可能在某些情况下被更改的,这就需要对这些规则留下动态屏蔽的能力。而实际上经常进行改变的,是对于前面绿灯-前进和前面有人-停止,这两个规则优先次序的判断逻辑,这个部分无疑是应该完全用规则引擎来管理。然而实际应用的情况要复杂的多,比如一张订单可以包括10个货物栏。这个时候,首先我们要明确知道这个规定注定会影响数据的存储逻辑,而数据的存储逻辑实际上是应该放在数据访问层中的。下订单这个业务行为也非常难与定义为一种业务逻辑还是一种行为职责,也就是产生订单这个行为是用一个程序的动作去实现,还是用一个规则引擎的规则实现?当然你可以先使用一个程序的动作实现,然后确定一个屏蔽的方法调用。而实际上我们遇到的情况将比这个复杂的多,需要你作出非常多的权衡。而实际上确实存在这样的一种可能,也就是你的程序的业务层中将不会再有具体的业务行为的业务对象,而只是一些单纯的数据对象和一些的方法对象,而这两者之间的联系仅仅依靠规则引擎来连接。而我认为在这样的情况下kiss将是必须遵守的。
所以第一个问题的答案是:你不应该自己选择。如果你要自己选择,那不就回到了原来的做法、在程序里写一大堆if...else...吗?那还要规则引擎来干什么呢?还是用上面这个例子,你可以再加上一条规则:“如果(绿灯亮 并且 前方有人),问候车前行人的母亲”。 而实际上对于需求分析的影响将是使用规则引擎造成的一个最为值得关注的问题,需要使用更加新鲜的分析方法。原来的基于数据和过程的认识系统,必须将过程和过程中的逻辑判断区分开来,并且进一步将逻辑判断划分为规则和流程所自身私有的规则加以区分。实际上这就意味着工作流引擎应该和规则引擎互相的可以调用,也就是说在每一个流程的节点都可以植入一个规则引擎的接口。(而实际上我认为是有AOP来设计一种规则和流程公用的引擎将是一种思路。) 同时由于规则引擎的引入,将会给测试造成的影响也是非常多,这一点大家应该比较好理解。实际全面的应用规则引擎将给你的日记开发的全过程造成非常重要的影响,而首先要解决的问题就是你必须决定要把什么东西放到规则引擎去完成,基本上可以认为一个项目的成功与否在这样的情况下关键就在此。 呵呵,oz6兄的这些想法看起来和我想的有点类似,要考虑oz6心目中的这个规则引擎会是一个不简单的事情。当然,按照gigix所描述的现有规则引擎,这种想法似乎不应该称为规则引擎。或者从另外一个方面来看,现有的规则引擎也许算是这种想法的一个应用场景相对简单的实现,我姑且称这种想法为大范围规则引擎。对于AOP可能是解决大范围规则引擎的可能思路这个想法,我的看法是AOP作为一个工具,确实有可能为大范围规则引擎的实现提供一条可能的道路。不过,在我看来,从语言的角度上来说,AOP的存在尚未和Java、C++这一类语言的类型系统融洽共生(目前的AOP似乎有打破类型系统的危险),使用AOP来实现大范围规则引擎,可能存在巨大的潜在危险,这样实现出来的系统可能先天上会有精神分裂的倾向。 |
|
返回顶楼 | |
发表时间:2004-09-26
ozzzzzz 写道 而实际上对于需求分析的影响将是使用规则引擎造成的一个最为值得关注的问题,需要使用更加新鲜的分析方法。原来的基于数据和过程的认识系统,必须将过程和过程中的逻辑判断区分开来,并且进一步将逻辑判断划分为规则和流程所自身私有的规则加以区分。实际上这就意味着工作流引擎应该和规则引擎互相的可以调用,也就是说在每一个流程的节点都可以植入一个规则引擎的接口。(而实际上我认为是有AOP来设计一种规则和流程公用的引擎将是一种思路。) 采用规则引擎确实给需求导致深刻影响。 而且也影响你的体系结构设计。 在需求分析中我认为至少应该区分三种规则: 与业务逻辑无关的程序逻辑规则: 这个以前怎么做, 还怎么做 可变的业务规则: 分离出来由 rule engine 集中管理 ozzzzzz提到的不变的业务规则: 没想好, 这样的规则会很多吗? 业务规则本身可能还需要进一步的细分, 采用不同的处理方法: 例如: 数据库表内字段的约束规则, 例如价格不可低于100元。可能适合于交由数据库自己管理。 其他的规则如: 表内字段关系约束, 表间关系约束。 有一本书专门讲业务规则, 有兴趣可以参考 《business rule applied》 引用 也就是说在每一个流程的节点都可以植入一个规则引擎的接口
有一种开发方法,bertrand meyer 的 design by contract 和你的这个想法很接近。 design by contract 的主要想法就是 pre-condition, post-condition and invariant. 你所提到的很类似于它的pre-condition |
|
返回顶楼 | |
发表时间:2004-09-29
把楼上的帖子都详细看了一片,但是不知道为什么,我总觉得你们理解的规则引擎和我理解并且用过的有相当的差别。
首先说明一下,规则引擎是比工作流引擎层次要低的中间组件。并且还没有出现哪个规则引擎可以解析实际的业务规则。 其实问题的关键就集中在对于规则的理解,这里的规则,是否是指业务规则或者还是指逻辑规则(注意:业务规则中不仅仅包含逻辑规则,还包括许多语义规则等)。再来看第二个问题,gigix所谈的规则引擎与实际的工作流引擎的差别,工作流引擎按照WFMC的说明,重要包括节点和流转,而流转也就意味着路由,而有路由就意味着有规则,这里的规则是纯粹的逻辑规则(可以由简单的与、或、异或到复杂的逻辑门),而由逻辑规则衍生的动作便是熟悉的(循环、分支与顺序),熟悉普通逻辑学的朋友知道有名的三段论(命题、推论、判断),规则引擎在这其中究竟是起怎么样的作用,我想大家还是需要好好交流。 以我所用的beanshell为例子,它是一个解析符合正则文法的逻辑描述的引擎,它的作用是对用对象描述或者正则文法描述的逻辑规则进行解析,并动态绑定数据(或者理解成变量吧),从而动态获得逻辑规则的结果。而结果导致的行为,也就是所谓的if else 以及其它,则并非它所做的。一个规则引擎只回跟规则的描述有关,而不会跟规则执行结果导致的行为有关,否则,就不能叫引擎了。 再回头看一下工作流引擎,工作流引擎便是将一系列复杂的业务流程用相应的信息描述(对象也好,XML也好,数据库也好),定义好在符合某种条件的情况下选择特定的路由。 可以这么说吧,规则引擎只负责逻辑规则(这里我所指的逻辑包括语言逻辑和运算逻辑)的解析和执行,而工作流引擎则根据实际的值确定业务的执行。 |
|
返回顶楼 | |
发表时间:2004-09-29
总感觉类似haskell的combinator是可以在这个方向上大展身手的。
用combinator直接开发大型应用我总是感觉有点没头苍蝇。因为combinator纯粹是自底向上的方法。 不过,规则编写本来就应该尽量declarative, 不要有太多抽象了。 比如,这几天写的对一些输入的validator,用xml文件来配置validator class。 比如,对一个输入项,我希望它的长度小于5, 并且是个整数,我可以这样: <item name="lastname"> <handler name="com.xxx.yyy.LengthFormat"> <arg name="length" value="5"/> </handler> <handler name="com.xxx.yyy.NumberFormat"/> </item> 串接两个不同的handler class来顺序判断。 这大概也算一个小小的rule engine了吧? 但是这种手工的rule engine非常简陋,不灵活。比如,我没法说:或者是一个number,或者是长度小于5的字符串。 如果我要求一个大于5的整数,也还要自己再写一个validator class。 其实,如果是haskell combinator的语法,我的串行检验的xml的对应版本就是 numberFormat >> lengthFormat 5 对那个或者或者的要求就是: numberFormat `mplus` LengthFormat 5 对后面哪个规则之间要传递信息的就是: numberFormat >>= predicateFormat (>5); 简单,灵活。只要写一些基本的validator作为基础,凭借monadic combinator强大的表达能力,可以编写任意复杂强大的rule。 所谓太极生两仪,两仪生四象,四象生八卦,生生不息,大千世界都可以从若干个简单的小组合子构造出来。 再比如那个红灯绿灯的例子,如果用monadic combinator,是这样: on_light color action = do r <- getColor when (r==color); action green_light = on_light green go red_light = on_light red stop pedestrian = do r <- is_pedestrian_ahead when r stop green_light >> red_light >> pedestrian 三个不同的规则是三个组合子,组合起来就成了。 gigix说规则间不互相通信,我总觉得这样的规则太过局限了。岂不是连我那个检查大于5的整数这种玩具都做不了? 不过没有真正接触过实际工作中的rule engine,就是瞎说一下。很有可能错误百出。见谅见谅! |
|
返回顶楼 | |