本文對(duì)Java規(guī)則引擎與其API(JSR-94)及相關(guān)實(shí)現(xiàn)做了較詳細(xì)的介紹,對(duì)其體系結(jié)構(gòu)和API應(yīng)用有較詳盡的描述,并指出Java規(guī)則引擎,規(guī)則語言,JSR-94的相互關(guān)系,以及JSR-94的不足之處和展望
復(fù)雜企業(yè)級(jí)項(xiàng)目的開發(fā)以及其中隨外部條件不斷變化的業(yè)務(wù)規(guī)則(business logic),迫切需要分離商業(yè)決策者的商業(yè)決策邏輯和應(yīng)用開發(fā)者的技術(shù)決策,并把這些商業(yè)決策放在中心數(shù)據(jù)庫或其他統(tǒng)一的地方,讓它們能在運(yùn)行時(shí)(即商務(wù)時(shí)間)可以動(dòng)態(tài)地管理和修改從而提供軟件系統(tǒng)的柔性和適應(yīng)性。規(guī)則引擎正是應(yīng)用于上述動(dòng)態(tài)環(huán)境中的一種解決方法。
本文第一部分簡要介紹了規(guī)則引擎的產(chǎn)生背景和基于規(guī)則的專家系統(tǒng),第二部分介紹了什么是規(guī)則引擎及其架構(gòu)和算法,第三部分介紹了商業(yè)產(chǎn)品和開源項(xiàng)目實(shí)現(xiàn)等各種Java規(guī)則引擎,第四部分對(duì)Java規(guī)則引擎API(JSR-94)作了詳細(xì)介紹,講解了其體系結(jié)構(gòu),管理API和運(yùn)行時(shí)API及相關(guān)安全問題,第五部分則對(duì)規(guī)則語言及其標(biāo)準(zhǔn)化作了探討,第六部分給出了一個(gè)使用Java規(guī)則引擎API的簡單示例,第七部分給予小結(jié)和展望。
1、 介紹
1.1 規(guī)則引擎產(chǎn)生背景
企業(yè)管理者對(duì)企業(yè)級(jí)IT系統(tǒng)的開發(fā)有著如下的要求:(1)為提高效率,管理流程必須自動(dòng)化,即使現(xiàn)代商業(yè)規(guī)則異常復(fù)雜(2)市場(chǎng)要求業(yè)務(wù)規(guī)則經(jīng)常變化,IT系統(tǒng)必須依據(jù)業(yè)務(wù)規(guī)則的變化快速、低成本的更新(3)為了快速、低成本的更新,業(yè)務(wù)人員應(yīng)能直接管理IT系統(tǒng)中的規(guī)則,不需要程序開發(fā)人員參與。
而項(xiàng)目開發(fā)人員則碰到了以下問題:
(1)程序=算法+數(shù)據(jù)結(jié)構(gòu),有些復(fù)雜的商業(yè)規(guī)則很難推導(dǎo)出算法和抽象出數(shù)據(jù)模型
(2)軟件工程要求從需求->設(shè)計(jì)->編碼,然而業(yè)務(wù)規(guī)則常常在需求階段可能還沒有明確,在設(shè)計(jì)和編碼后還在變化,業(yè)務(wù)規(guī)則往往嵌在系統(tǒng)各處代碼中
(3)對(duì)程序員來說,系統(tǒng)已經(jīng)維護(hù)、更新困難,更不可能讓業(yè)務(wù)人員來管理。
基于規(guī)則的專家系統(tǒng)的出現(xiàn)給開發(fā)人員以解決問題的契機(jī)。規(guī)則引擎由基于規(guī)則的專家系統(tǒng)中的推理引擎發(fā)展而來。下面簡要介紹一下基于規(guī)則的專家系統(tǒng)。
1.2 基于規(guī)則的專家系統(tǒng)(RBES)
專家系統(tǒng)是人工智能的一個(gè)分支,它模仿人類的推理方式,使用試探性的方法進(jìn)行推理,并使用人類能理解的術(shù)語解釋和證明它的推理結(jié)論。專家系統(tǒng)有很多分類:神經(jīng)網(wǎng)絡(luò)、基于案例推理和基于規(guī)則系統(tǒng)等。
RBES包括三部分:Rule Base(knowledge base)、Working Memory(fact base)和Inference Engine(推理引擎)。它們的結(jié)構(gòu)如下所示:
圖1.基于規(guī)則的專家系統(tǒng)組成
如上圖所示,推理引擎包括三部分:Pattern Matcher、Agenda和Execution Engine。Pattern Matcher何時(shí)執(zhí)行哪個(gè)規(guī)則;Agenda管理PatternMatcher挑選出來的規(guī)則的執(zhí)行次序;Execution Engine負(fù)責(zé)執(zhí)行規(guī)則和其他動(dòng)作。
推理引擎通過決定哪些規(guī)則滿足事實(shí)或目標(biāo),并授予規(guī)則優(yōu)先級(jí),滿足事實(shí)或目標(biāo)的規(guī)則被加入議程。存在兩者推理方式:演繹法(Forward-Chaining正向鏈)和歸納法(Backward-Chaining反向鏈)。演繹法從一個(gè)初始的事實(shí)出發(fā),不斷地應(yīng)用規(guī)則得出結(jié)論(或執(zhí)行指定的動(dòng)作)。而歸納法則是從假設(shè)出發(fā),不斷地尋找符合假設(shè)的事實(shí)。
2、 規(guī)則引擎
2.1 業(yè)務(wù)規(guī)則
一個(gè)業(yè)務(wù)規(guī)則包含一組條件和在此條件下執(zhí)行的操作,它們表示業(yè)務(wù)規(guī)則應(yīng)用程序的一段業(yè)務(wù)邏輯。業(yè)務(wù)規(guī)則通常應(yīng)該由業(yè)務(wù)分析人員和策略管理者開發(fā)和修改,但有些復(fù)雜的業(yè)務(wù)規(guī)則也可以由技術(shù)人員使用面向?qū)ο蟮募夹g(shù)語言或腳本來定制。業(yè)務(wù)規(guī)則的理論基礎(chǔ)是:設(shè)置一個(gè)或多個(gè)條件,當(dāng)滿足這些條件時(shí)會(huì)觸發(fā)一個(gè)或多個(gè)操作。
2.2 規(guī)則引擎
什么是規(guī)則引擎?規(guī)則引擎是如何執(zhí)行規(guī)則的?這可以稱之為"什么"與"如何"的問題。到底規(guī)則引擎是什么還是目前業(yè)界一個(gè)比較有爭議的問題,在JSR-94種也幾乎沒有定義??梢赃@樣認(rèn)為充分定義和解決了"如何"的問題,"什么"問題本質(zhì)上也迎刃而解。也許這又是一種"先有蛋還是先有雞"哲學(xué)爭論。今后標(biāo)準(zhǔn)規(guī)則語言的定義和推出及相關(guān)標(biāo)準(zhǔn)的制定應(yīng)該可以給這樣的問題和爭論劃上一個(gè)句號(hào)。本文中,暫且這樣述說什么是規(guī)則引擎:規(guī)則引擎由推理引擎發(fā)展而來,是一種嵌入在應(yīng)用程序中的組件,實(shí)現(xiàn)了將業(yè)務(wù)決策從應(yīng)用程序代碼中分離出來,并使用預(yù)定義的語義模塊編寫業(yè)務(wù)決策。接受數(shù)據(jù)輸入,解釋業(yè)務(wù)規(guī)則,并根據(jù)規(guī)則做出業(yè)務(wù)決策。
2.3 規(guī)則引擎的使用方式
由于規(guī)則引擎是軟件組件,所以只有開發(fā)人員才能夠通過程序接口的方式來使用和控制它,規(guī)則引擎的程序接口至少包含以下幾種API:加載和卸載規(guī)則集的API;數(shù)據(jù)操作的API;引擎執(zhí)行的API。開發(fā)人員在程序中使用規(guī)則引擎基本遵循以下5個(gè)典型的步驟:創(chuàng)建規(guī)則引擎對(duì)象;向引擎中加載規(guī)則集或更換規(guī)則集;向引擎提交需要被規(guī)則集處理的數(shù)據(jù)對(duì)象集合;命令引擎執(zhí)行;導(dǎo)出引擎執(zhí)行結(jié)果,從引擎中撤出處理過的數(shù)據(jù)。使用了規(guī)則引擎之后,許多涉及業(yè)務(wù)邏輯的程序代碼基本被這五個(gè)典型步驟所取代。
一個(gè)開放的業(yè)務(wù)規(guī)則引擎應(yīng)該可以"嵌入"在應(yīng)用程序的任何位置,不同位置的規(guī)則引擎可以使用不同的規(guī)則集,用于處理不同的數(shù)據(jù)對(duì)象。此外,對(duì)使用引擎的數(shù)量沒有限制。
2.4 規(guī)則引擎架構(gòu)與推理
規(guī)則引擎的架構(gòu)如下圖所示:
圖2. 業(yè)務(wù)規(guī)則引擎架構(gòu)
規(guī)則引擎的推理步驟如下:a. 將初始數(shù)據(jù)(fact)輸入至工作內(nèi)存(Working Memory)。b. 使用Pattern Matcher將規(guī)則庫(Rules repository)中的規(guī)則(rule)和數(shù)據(jù)(fact)比較。c. 如果執(zhí)行規(guī)則存在沖突(conflict),即同時(shí)激活了多個(gè)規(guī)則,將沖突的規(guī)則放入沖突集合。d. 解決沖突,將激活的規(guī)則按順序放入Agenda。e. 執(zhí)行Agenda中的規(guī)則。重復(fù)步驟b至e,直到執(zhí)行完畢Agenda中的所有規(guī)則。
任何一個(gè)規(guī)則引擎都需要很好地解決規(guī)則的推理機(jī)制和規(guī)則條件匹配的效率問題。
當(dāng)引擎執(zhí)行時(shí),會(huì)根據(jù)規(guī)則執(zhí)行隊(duì)列中的優(yōu)先順序逐條執(zhí)行規(guī)則執(zhí)行實(shí)例,由于規(guī)則的執(zhí)行部分可能會(huì)改變工作區(qū)的數(shù)據(jù)對(duì)象,從而會(huì)使隊(duì)列中的某些規(guī)則執(zhí)行實(shí)例因?yàn)闂l件改變而失效,必須從隊(duì)列中撤銷,也可能會(huì)激活原來不滿足條件的規(guī)則,生成新的規(guī)則執(zhí)行實(shí)例進(jìn)入隊(duì)列。于是就產(chǎn)生了一種"動(dòng)態(tài)"的規(guī)則執(zhí)行鏈,形成規(guī)則的推理機(jī)制。這種規(guī)則的"鏈?zhǔn)?反應(yīng)完全是由工作區(qū)中的數(shù)據(jù)驅(qū)動(dòng)的。
規(guī)則條件匹配的效率決定了引擎的性能,引擎需要迅速測(cè)試工作區(qū)中的數(shù)據(jù)對(duì)象,從加載的規(guī)則集中發(fā)現(xiàn)符合條件的規(guī)則,生成規(guī)則執(zhí)行實(shí)例。1982年美國卡耐基·梅隆大學(xué)的Charles L. Forgy發(fā)明了一種叫Rete算法,很好地解決了這方面的問題。目前世界頂尖的商用業(yè)務(wù)規(guī)則引擎產(chǎn)品基本上都使用Rete算法。
2.5 規(guī)則引擎的算法
大部分規(guī)則引擎產(chǎn)品的算法,基本上都來自于Dr. Charles Forgy在1979年提出的RETE算法及其變體,Rete算法是目前效率最高的一個(gè)Forward-Chaining推理算法,Drools項(xiàng)目是Rete算法的一個(gè)面向?qū)ο蟮腏ava實(shí)現(xiàn),Rete算法其核心思想是將分離的匹配項(xiàng)根據(jù)內(nèi)容動(dòng)態(tài)構(gòu)造匹配樹,以達(dá)到顯著降低計(jì)算量的效果。詳情請(qǐng)見CIS587:The RETE Algorithm,The Rete Algorithm,RETE演算法,《專家系統(tǒng)原理與編程》中第11章等。
3、 Java規(guī)則引擎
目前主流的規(guī)則引擎組件多是基于Java和C++程序語言環(huán)境,已經(jīng)有多種Java規(guī)則引擎商業(yè)產(chǎn)品與開源項(xiàng)目的實(shí)現(xiàn),其中有的已經(jīng)支持JSR94,有的正朝這個(gè)方向做出努力,列出如下:
3.1 Java規(guī)則引擎商業(yè)產(chǎn)品
Java規(guī)則引擎商業(yè)產(chǎn)品主要有(Jess不是開源項(xiàng)目,它可以免費(fèi)用于學(xué)術(shù)研究,但用于商業(yè)用途則要收費(fèi)):
3.2 Java規(guī)則引擎開源項(xiàng)目
開源項(xiàng)目的實(shí)現(xiàn)主要包括:
Drools - Drools規(guī)則引擎應(yīng)用Rete算法的改進(jìn)形式Rete-II算法。從內(nèi)部機(jī)制上講,它使用了和Forgy的算法相同的概念和方法,但是增加了可與面向?qū)ο笳Z言無縫連接的節(jié)點(diǎn)類型。
Mandarax 基于反向推理(歸納法)。能夠較容易地實(shí)現(xiàn)多個(gè)數(shù)據(jù)源的集成。例如,數(shù)據(jù)庫記錄能方便地集成為事實(shí)集(facts sets),reflection用來集成對(duì)象模型中的功能。目前不支持JSR 94
OFBiz Rule Engine - 支持歸納法(Backward chaining).最初代碼基于Steven John Metsker的"Building Parsers in Java",不支持JSR 94
JLisa - JLisa是用來構(gòu)建業(yè)務(wù)規(guī)則的強(qiáng)大框架,它有著擴(kuò)展了LISP優(yōu)秀特色的優(yōu)點(diǎn),比Clips還要強(qiáng)大.這些特色對(duì)于多范例軟件的開發(fā)是至關(guān)重要的.支持JSR 94
其它的開源項(xiàng)目實(shí)現(xiàn)有諸如Algernon, TyRuBa, JTP, JEOPS, InfoSapient, RDFExpert, Jena 2, Euler, JLog, Pellet OWL Reasoner, Prova, OpenRules, SweetRules, JShop2等等。
4、 Java規(guī)則引擎API(JSR-94)
4.1 簡介
過去大部分的規(guī)則引擎開發(fā)并沒有規(guī)范化,有其自有的API,這使得其與外部程序交互集成不夠靈活。轉(zhuǎn)而使用另外一種產(chǎn)品時(shí)往往意味需要重寫應(yīng)用程序邏輯和API調(diào)用,代價(jià)較大。規(guī)則引擎工業(yè)中標(biāo)準(zhǔn)的缺乏成為令人關(guān)注的重要方面。2003年11月定稿并于2004年8月最終發(fā)布的JSR 94(Java規(guī)則引擎API)使得Java規(guī)則引擎的實(shí)現(xiàn)得以標(biāo)準(zhǔn)化。
Java規(guī)則引擎API由javax.rules包定義,是訪問規(guī)則引擎的標(biāo)準(zhǔn)企業(yè)級(jí)API。Java規(guī)則引擎API允許客戶程序使用統(tǒng)一的方式和不同廠商的規(guī)則引擎產(chǎn)品交互,就像使用JDBC編寫?yīng)毩⒂趶S商訪問不同的數(shù)據(jù)庫產(chǎn)品一樣。Java規(guī)則引擎API包括創(chuàng)建和管理規(guī)則集合的機(jī)制,在Working Memory中添加,刪除和修改對(duì)象的機(jī)制,以及初始化,重置和執(zhí)行規(guī)則引擎的機(jī)制。
4.2 簡介Java規(guī)則引擎API體系結(jié)構(gòu)
Java規(guī)則引擎API分為兩個(gè)主要部分:運(yùn)行時(shí)客戶API(the Runtime client API)和規(guī)則管理API(the rules administration API)。
聯(lián)系客服