这两天写一个研究性的材料,主要是关于基于规则驱动的业务开发,于是找了相关资料来看,以下是一篇我认为结合MS的WWF中ruleEngine,讲得很通俗易懂的,关于规则的原理和实现逻辑的文章。看完后,基本能对规则的实现原理和适用场景有一个概要的认识,转过来,便于收藏。
原文地址如下:
http://www.csharpwin.com/csharpspace/2673.shtml
工作流中的RuleEngine是非常重要的一块功能,主要用来计算一些表达式的真假值。
其他一些工作流中一般是使用外挂的一些RuleEngine,或者自己实现自己的特定的Engine。
WWF中集成了一个功能强大的RuleEnggine。这里是英文文章原文:http://msdn.microsoft.com/windowsvista/default.aspx?pull=/library/en-us/dnlong/html/intWF_FndRlsEng.asp
WWF中有两类规则:Condition和Forward Chaining。
1:Condition
Condtion是一种简单的逻辑表达式,比如“if (a>5) then b=6;”
Condtion一般用在IfElseBranch;While;Replicator;Condition Activety Group中
Condtion有两种表达方式,其一是CodeCondtion,顾名思义,就是自己写判断代码;其二是RuleCondtionRefernce,定义在一个xml文件中(xxx.Rules文件)。建议使用第二种,因为这种逻辑可以随时修改。这是一个Rule的xml文件的例子
RuleSet是一组Rule的集合。不同的是,这些Rule是有优先级(Priority)的。可以用在诸如FilterPolicy中。
RuleSet的这些Rule的计算也是有特点的:根据优先级和判断条件的“关联性”在运行时来重新计算。重新计算的含义是,从优先级最高的依次在计算一次,而不是计算完关联之后回到原点继续计算 。
举个例子,现在有这么四个条件判断
IF A = 15
THEN B = 5
Rule3 (P=3)
IF C = 5
THEN B = 10
Rule2 (P=2)
IF D = 2
THEN A = 15
Rule1 (P=1)
IF B = 5
THEN E = 7
初始数据如下:
- A = 0
- B = 0
- C = 5
- D = 2
- E = 0
运行之后,结果如下:
- A = 15
- B = 5
- C = 5
- D = 2
- E = 7
运行逻辑是这样的:首先执行Rule4,不符合;执行Rule3,设置B=10;执行Rule2,设置A=15;因为A的值已经改变,所以重新返回Rule4,执行设置B=5;依次检查都不符合条件;执行Rule1,设置E=7。
2:ForwardChaining
这一个有三种方式:Inplicit;Attributed-Based;Explicit
Inplicit:隐式表达式。隐式表达就是不指名条件变量之间的关系,直接写。比如
B=2;
Rule2 if(B=2)
C=4;
Rule2中的条件变量B就是隐式的和Rule1有关的。每当Rule1执行设置B的值的时候,Rule都需要重新计算。这一写都是自动完成的。
Attributed-Based:通过属性来标明哪些是对条件表达式的修改。属性有三种:RuleRead,RuleWrite,RuleInvoke。
比如,上边的例子中,如果Rule1中不是直接设置B=2,而是调用一个函数F1,F1设置了B的值,那么,我们就需要给F1一个属性RuleWrite:
if(A=2)
F1()
Rule2
if(B=2)
c=5
[RuleWrite("B")]
F1()
{
B=2;
}
如果调用还要复杂,F1又调用另外一个函数F2,F2才真正修改B的话,就得使用RuleInvoke属性了,比如
if(A=2)
F1()
Rule 2
if(B=2)
c=5;
[RuleInvoke("F2")]
F1()
{
F2();
}
[RuleWrite("B")]
F2()
{
B=2;
}
至于Expicit显式方式声明,可以用前两种来组合实现,一般用到的较少。Expicit使用Update()方法来更新变量的值。