隨筆 - 19, 文章 - 93, 評(píng)論 - 17, 引用 - 0
          數(shù)據(jù)加載中……

          (三): Drools規(guī)則引擎 (上)

          從今天開(kāi)始,我們將分兩期來(lái)詳細(xì)的介紹Drools規(guī)則引擎的原理,和各關(guān)鍵類的使用方法。

          Drools 規(guī)則引擎(上)

          1. 概述 :
          Drools 分為兩個(gè)主要部分:構(gòu)建( Authoring )和運(yùn)行時(shí)( Runtime )。

          構(gòu)建的過(guò)程涉及到 .drl .xml 規(guī)則文件的創(chuàng)建,它們被讀入一個(gè)解析器,使用 ANTLR 3 語(yǔ)法進(jìn)行解析。解析器對(duì)語(yǔ)法進(jìn)行正確性的檢查,然后產(chǎn)生一種中間結(jié)構(gòu)“ descr ”, descr AST 來(lái)描述規(guī)則。 AST 然后被傳到 PackageBuilder ,由 PackagBuilder 來(lái)產(chǎn)生 Packaged 對(duì)象。 PackageBuilder 還承擔(dān)著一些代碼產(chǎn)生和編譯的工作,這些對(duì)于產(chǎn)生 Package 對(duì)象都時(shí)必需的。 Package
          對(duì)象是一個(gè)可以配置的,可序列化的,由一個(gè)或多個(gè)規(guī)則組成的對(duì)象。下圖闡明了上述過(guò)程:
          ?
          Figure 1.1
          Authoring Components

          RuleBase 是一個(gè)運(yùn)行時(shí)組件,它包含了一個(gè)或多個(gè) Package 對(duì)象。可以在任何時(shí)刻將一個(gè) Package 對(duì)象加入或移出 RuleBase 對(duì)象。一個(gè) RuleBase 對(duì)象可以在任意時(shí)刻實(shí)例化一個(gè)或多個(gè) WorkingMemory 對(duì)象,在它的內(nèi)部保持對(duì)這些 WorkingMemory 的弱引用。 WorkingMemory 由一系列子組件組成。當(dāng)應(yīng)用程序中的對(duì)象被 assert 進(jìn) WorkingMemory ,可能會(huì)導(dǎo)致一個(gè)或多個(gè) Activation 的產(chǎn)生,然后由 Agenda 負(fù)責(zé)安排這些 Activation 的執(zhí)行。下圖說(shuō)明了上述過(guò)程:

          ?
          Figure 1.2 .?Runtime Components

          2.構(gòu)建(Authoring):

          主要有三個(gè)類用來(lái)完成構(gòu)建過(guò)程:DrlParser, XmlParser PackageBuilder。兩個(gè)解析器類從傳入的Reader實(shí)例產(chǎn)生descr AST模型。PackageBuilder提供了簡(jiǎn)便的API,使你可以忽略那兩個(gè)類的存在。這兩個(gè)簡(jiǎn)單的方法是:“addPackageFromDrl”和“addPackageFromXml”,兩個(gè)都只要傳入一個(gè)Reader實(shí)例作為參數(shù)。下面的例子說(shuō)明了如何從classpath中的xmldrl文件創(chuàng)建一個(gè)Package對(duì)象。注意:所有傳入同一個(gè)PackageBuilder實(shí)例的規(guī)則源,都必須是在相同的package 命名空間(namespace)中。

          PackageBuilder?builder?=?new?PackageBuilder();
          builder.addPackageFromDrl(?
          new?InputStreamReader(?getClass().getResourceAsStream(?"package1.drl"?)?)?);
          builder.addPackageFromXml(?
          new?InputStreamReader(?getClass().getResourceAsStream(?"package2.drl"?)?)?);
          Package?pkg?
          =?builder.getPackage();


          Figure 2.1 PackageBuilder

          PackageBuilder是可以配置的,使用PackageBuilderConfiguration。通常,你可以指定另一個(gè)parent ClassLoader和用什么編譯器(compiler),默認(rèn)是Eclipse JDT。下面顯示了如何指定JANINO編譯器:

          PackageBuilderConfiguration?conf?=?new?PackageBuilderConfiguration();
          conf.setCompiler(?PackageBuilderConfiguration.JANINO?);
          PackageBuilder?builder?
          =?new?PackageBuilder(?conf?);

          Figure 2.2 .?PackageBuilderConfiguration

          3
          RuleBase:

          Figure 3.1 .?RuleBase

          一個(gè)RuleBase包含了多個(gè)將被使用的規(guī)則包(packages of rules)。一個(gè)RuleBase是可以序列化的,所以它可以被配置到JNDI或其他類似的服務(wù)。通常,第一次使用時(shí),一個(gè)RuleBase被創(chuàng)建并緩存。RuleBaseRuleBaseFactory來(lái)實(shí)例化,默認(rèn)返回一個(gè)ReteOO RuleBase。可以傳入?yún)?shù)來(lái)指定采用ReteOOLeaps。然后,用addPackage方法加入Package實(shí)例。你可以加入有相同命名空間(namespace)的多個(gè)Package

          RuleBase?ruleBase??=?RuleBaseFactory.newRuleBase();
          ruleBase.addPackage(pkg);

          Figure 3.2. RuleBaseFactory

          一個(gè) rulebase instance 是線程安全的,所有你可以在你的應(yīng)用中,讓一個(gè) rulebase instance 在多個(gè)線程中共享。對(duì)于一個(gè) rulebase 的最通常的操作是產(chǎn)生一個(gè)新的 WorkingMemory

          這個(gè) rulebase 保持著到它所產(chǎn)生的 WorkingMemoryd 的弱引用,所以在長(zhǎng)時(shí)間運(yùn)行的 WorkingMemory 中,如果 rules 發(fā)生改變,這些 WorkingMemory 可以即使的根據(jù)最新的 rules 進(jìn)行更新,而不必重啟 WorkingMemory 。你也可以指定 RuleBase 不必保持一個(gè)弱引用,但是你要保證 RuleBase 不用更新。

          ruleBase.newWorkingMemory();?? // ?maintains?a?weak?reference.
          ruleBase.newWorkingMemory(? false ?);? // ?do?not?maintain?a?weak?reference

          任何時(shí)候, Package 可以被加入或移除;所有的改變都會(huì)被反映到現(xiàn)存的 WorkingMemory 中。不要忘了調(diào)用 fireAllRules() Activations 激發(fā)。

          ruleBase.addPackage(?pkg??);?? // ?Add?a?package?instance
          ruleBase.removePackage(? " org.com.sample " ??);?? // ?remove?a?package,?and?all?its?parts, by?it's?namespace
          ruleBase.removeRule(? " org.com.sample " ,? " my?rule " ?);? // ?remove?a?specific?rule?from?a namespace

          雖然有刪除一個(gè)單獨(dú)規(guī)則的方法,但是卻沒(méi)有加入一個(gè)單獨(dú)規(guī)則的方法(要達(dá)到這個(gè)目的只有加入一個(gè)只有一條規(guī)則的 package )。

          <!--[if !supportEmptyParas]-->

          RuleBaseConfigurator 可以指定 RuleBase 的附加行為。在加入 RuleBase 后, RuleBaseConfiguration 就變成不可變對(duì)象。

          RuleBaseConfiguration?conf? = ? new ?RuleBaseConfiguration();

          conf.setProperty(?RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
          ??????????????????RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY?);

          RuleBase?ruleBase?
          = ? new ?ReteooRuleBase(?conf?);

          兩個(gè)主要的屬性是: PROPERT_ASSERT_BEHAVIOR PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR (在以后的部分中會(huì)解釋)。所有的屬性值都是 RuleBaseConfiguration 類中的靜態(tài)域常量。


          Figure 3.3 RuleBaseConfiguration

          posted on 2006-12-03 09:54 BPM 閱讀(958) 評(píng)論(0)  編輯  收藏 所屬分類: 規(guī)則引擎

          主站蜘蛛池模板: 吕梁市| 甘肃省| 五家渠市| 徐闻县| 方正县| 江城| 陇南市| 雅江县| 武安市| 恭城| 崇信县| 河北省| 陵水| 胶州市| 闵行区| 息烽县| 县级市| 涟源市| 新闻| 随州市| 微博| 沈丘县| 乐亭县| 山东省| 兴文县| 寿阳县| 仪征市| 凤山县| 图木舒克市| 申扎县| 合作市| 博客| 丰原市| 关岭| 曲阳县| 乡宁县| 棋牌| 阿克| 江油市| 无极县| 夹江县|