????? 學(xué)習(xí)JBoss Rules有幾天了,因?yàn)檫@方面的中文資料較少,所以這幾天都在看官網(wǎng)上的manual。這是一份不錯(cuò)的教程,我把我看的一些重要的東西翻譯整理了一下,希望可以對(duì)想學(xué)習(xí)JBoss Rules的同學(xué)們提供一點(diǎn)幫助。
?????? 在開(kāi)始這份教程之前,我先簡(jiǎn)要介紹一下JBoss Rules:
?????? JBoss Rules 的前身是Codehaus的一個(gè)開(kāi)源項(xiàng)目叫Drools。最近被納入JBoss門(mén)下,更名為JBoss Rules,成為了JBoss應(yīng)用服務(wù)器的規(guī)則引擎。
?????? Drools是為Java量身定制的基于Charles? Forgy的RETE算法的規(guī)則引擎的實(shí)現(xiàn)。具有了OO接口的RETE,使得商業(yè)規(guī)則有了更自然的表達(dá)。
?
?????? 既然JBoss Rules是一個(gè)商業(yè)規(guī)則引擎,那我們就要先知道到底什么是Rules,即規(guī)則。在JBoss Rules中,規(guī)則是如何被表示的
Rules
一條規(guī)則是對(duì)商業(yè)知識(shí)的編碼。一條規(guī)則有
attributes
,一個(gè)
Left Hand Side
(
LHS
)和一個(gè)
Right Hand Side
(
RHS
)。
Drools
允許下列幾種
attributes
:
salience
,
agenda-group
,
no-loop
,
auto-focus
,
duration
,
activation-group
。
rule?“
<
name
>
”????
????
<
attribute
>
?
<
value
>
????
????when????????
????????
<
LHS
>
????
????then????????
????????
<
RHS
>
end
規(guī)則的
LHS
由一個(gè)或多個(gè)條件(
Conditions
)組成。當(dāng)所有的條件(
Conditions
)都滿(mǎn)足并為真時(shí),
RHS
將被執(zhí)行。
RHS
被稱(chēng)為結(jié)果(
Consequence
)。
LHS
和
RHS
類(lèi)似于:
if
?(?
<
LHS
>
?)?{
????
<
RHS
>
}
規(guī)則可以通過(guò)
package
關(guān)鍵字同一個(gè)命名空間(
namespace
)相關(guān)聯(lián);其他的規(guī)則引擎可能稱(chēng)此為規(guī)則集(
Rule Set
)。一個(gè)
package
聲明了
imports
,
global
變量,
functions
和
rules
。
package
?com.sample
import
?java.util.List
import
?com.sample.Cheese
global?List?cheeses
function?
void
?exampleFunction(Cheese?cheese)?{
????System.out.println(?cheese?);
}
rule?“A?Cheesy?Rule”
????when
????????cheese?:?Cheese(?type?
==
?
"
stilton
"
?)
????then
????????exampleFunction(?cheese?);
????????cheeses.add(?cheese?);
end
對(duì)新的數(shù)據(jù)和被修改的數(shù)據(jù)進(jìn)行規(guī)則的匹配稱(chēng)為模式匹配(
Pattern Matching
)。進(jìn)行匹配的引擎稱(chēng)為推理機(jī)(
Inference Engine
)。被訪問(wèn)的規(guī)則稱(chēng)為
ProductionMemory
,被推理機(jī)進(jìn)行匹配的數(shù)據(jù)稱(chēng)為
WorkingMemory
。
Agenda
管理被匹配規(guī)則的執(zhí)行。推理機(jī)所采用的模式匹配算法有下列幾種:
Linear
,
RETE
,
Treat
,
Leaps
。
Drools
采用了
RETE
和
Leaps
的實(shí)現(xiàn)。
Drools
的
RETE
實(shí)現(xiàn)被稱(chēng)為
ReteOO
,表示
Drools
對(duì)
Rete
算法進(jìn)行了加強(qiáng)和優(yōu)化的實(shí)現(xiàn)。
一條規(guī)則的
LHS
由
Conditional Element
和域約束(
Field Constraints
)。下面的例子顯示了對(duì)一個(gè)
Cheese Fact
使用了字面域約束(
Literal Field Constraint
)
rule?
"
Cheddar?Cheese
"
????when
????????Cheese(?type?
==
?
"
cheddar
"
?)
????then
????????System.out.println(?
"
cheddar
"
?);
end
上面的這個(gè)例子類(lèi)似于:
public
?
void
?cheddarCheese(Cheese?cheese)?{
????
if
?(?cheese.getType().equals(
"
cheddar
"
)?{
????????System.out.println(?
"
cheddar
"
?);
????}
}
<!--[if !vml]--> <!--[endif]-->
規(guī)則引擎實(shí)現(xiàn)了數(shù)據(jù)同邏輯的完全解耦。規(guī)則并不能被直接調(diào)用,因?yàn)樗鼈儾皇欠椒ɑ蚝瘮?shù),規(guī)則的激發(fā)是對(duì)
WorkingMemory
中數(shù)據(jù)變化的響應(yīng)。結(jié)果(
Consequence
,即
RHS
)作為
LHS events
完全匹配的
Listener
。
當(dāng)
rules
被加入
Productioin Memory
后,
rules
被規(guī)則引擎用
RETE
算法分解成一個(gè)圖:
當(dāng)
Facts
被
assert
進(jìn)入
WorkingMemory
中后,規(guī)則引擎找到匹配的
ObjectTypeNode
,然后將此
Fact
傳播到下一個(gè)節(jié)點(diǎn)。
ObjectTypeNode
擁有一塊內(nèi)存來(lái)保存所有匹配的
facts
。在我們的例子中,下一個(gè)節(jié)點(diǎn)是一個(gè)域約束(
Field Constraint
),
type = = “cheddar”
。如果某個(gè)
Cheese
對(duì)象的類(lèi)型不是“
cheddar
”,這個(gè)
fact
將不會(huì)被傳播到網(wǎng)絡(luò)的下一個(gè)節(jié)點(diǎn)。如果是“
cheddar
”類(lèi)型,它將被記錄到
AlphaNode
的內(nèi)存中,并傳播到網(wǎng)絡(luò)的下一個(gè)節(jié)點(diǎn)。
AlphaNode
是古典
RETE
術(shù)語(yǔ),它是一個(gè)單輸入
/
單輸出的節(jié)點(diǎn)。最后通過(guò)
AlphaNode
的
fact
被傳播到
Terminal Node
。
Terminal Node
是最終節(jié)點(diǎn),到此我們說(shuō)這條規(guī)則被完全匹配,并準(zhǔn)備激發(fā)。
當(dāng)一條規(guī)則被完全匹配,它并沒(méi)有立刻被激發(fā)(在
RETE
中是這樣,但在
Leaps
中它會(huì)立刻被激發(fā))。這條規(guī)則和與其匹配的
facts
將激活被放入
Agenda
,由
Agenda
來(lái)負(fù)責(zé)安排激發(fā)
Activations
(指的是
rule + the matched facts
)。
下面的圖很清楚的說(shuō)明了
Drools
規(guī)則引擎的執(zhí)行過(guò)程:
數(shù)據(jù)被
assert
進(jìn)
WorkingMemory
后,和
RuleBase
中的
rule
進(jìn)行匹配(確切的說(shuō)應(yīng)該是
rule
的
LHS
),如果匹配成功這條
rule
連同和它匹配的數(shù)據(jù)(此時(shí)就叫做
Activation
)一起被放入
Agenda
,等待
Agenda
來(lái)負(fù)責(zé)安排激發(fā)
Activation
(其實(shí)就是執(zhí)行
rule
的
RHS
),上圖中的菱形部分就是在
Agenda
中來(lái)執(zhí)行的,
Agenda
就會(huì)根據(jù)沖突解決策略來(lái)安排
Activation
的執(zhí)行順序。