隨筆-61  評論-159  文章-0  trackbacks-0

          原文:http://www.javaeye.com/topic/190294
          一個典型的DRL文件:
          Java代碼
          ①package com.sample   //包名,不可以與關(guān)鍵字沖突  
          ②import com.sample.DroolsTest.Message;//本文件需要導(dǎo)入的類  
          ③global java.util.List myGlobalList;//全局變量  
          ④//定義函數(shù)體  
          function String hello(String name) {  
              return "Hello "+name+"!";  
          }  
           
          ⑤rule "myRule"    
          no-loop true  //執(zhí)行一次后,是否能被再次激活  
          salience 100  //優(yōu)先級別  
          ⑥when    
          m : Message( status == Message.HELLO, message : message )   
          ⑦then      
          m.setMessage( "Goodbye cruel world" );  
                  m.setStatus( Message.GOODBYE );  
                  update( m );  
              myGlobalList.add( "Hello World" );//使用global 變量  
              System.out.println( hello( "Bob" ) );//調(diào)用定義函數(shù)  
          End 

          ①package com.sample   //包名,不可以與關(guān)鍵字沖突
          ②import com.sample.DroolsTest.Message;//本文件需要導(dǎo)入的類
          ③global java.util.List myGlobalList;//全局變量
          ④//定義函數(shù)體
          function String hello(String name) {
              return "Hello "+name+"!";
          }

          ⑤rule "myRule" 
          no-loop true  //執(zhí)行一次后,是否能被再次激活
          salience 100  //優(yōu)先級別
          ⑥when 
          m : Message( status == Message.HELLO, message : message )
          ⑦then   
          m.setMessage( "Goodbye cruel world" );
            m.setStatus( Message.GOODBYE );
            update( m );
              myGlobalList.add( "Hello World" );//使用global 變量
              System.out.println( hello( "Bob" ) );//調(diào)用定義函數(shù)
          End

           

          ①package com.sample
          包名,不可以與關(guān)鍵字沖突。一個包通過名稱空間描繪,這樣很好的保持了一組規(guī)則的獨立性。
          ②import
          標(biāo)記就像java中的含義一樣。對于任何要用在規(guī)則中的對象,你需要指定完整的路徑和類型名。Drools從同名的java包中自動導(dǎo)入類。
          ③global
          如果多個包定義了同樣名稱的全局變量,它們必須使用同樣的類型,并且全部指向同一個全局值。全部變量通常用來返回數(shù)據(jù),獲得提供數(shù)據(jù)或服務(wù)給規(guī)則使用。為了使用全局變量,你必須:
          在規(guī)則文件中聲明全局變量并使用它,如:
          global java.util.List myGlobalList;
          rule "Using a global"
          when
              eval( true )
          then
              myGlobalList.add( "Hello World" );
          end
          在working memory上設(shè)置全局變量的值。最好是在將fact插入working memory之前設(shè)置完所有全局變量,如:
          List list = new ArrayList();
          WorkingMemory wm = rulebase.newStatefulSession();
          wm.setGlobal( "myGlobalList", list );
          ④function
          相對于正常的java類,函數(shù)是在你的規(guī)則代碼中放置語言代碼的方法。它們不可能做任何超過你可以在幫助類(在java中定義,被設(shè)置入規(guī)則的Working Memory中的類)中做到的事情。使用函數(shù)的優(yōu)點是可以將邏輯保存在一個地方,并且你可以在需要的時候改變函數(shù)(這樣做各有優(yōu)缺點)。函數(shù)最大的用處是被規(guī)則的推論(then)部分中的行為所調(diào)用,特別是當(dāng)一個行為操作需要反復(fù)被調(diào)用時(將公用代碼抽取出來成為一個函數(shù))。
          ⑤rule 名稱可以在“”下取任何名字。
          屬性列表:
          屬性 類型 默認值 功能描述
          no-loop Boolean false 設(shè)置no-loop為true可以阻止該規(guī)則被再次激活。
          salience integer 0 優(yōu)先級數(shù)字高的規(guī)則會比優(yōu)先級低的規(guī)則先執(zhí)行。
          agenda-group String MAIN 只有在具有焦點的agenda group中的規(guī)則才能夠激發(fā)。
          auto-focus Boolean false 如果該規(guī)則符合激活條件,則該規(guī)則所在agenda-group自動獲得焦點,允許規(guī)則激發(fā)。
          activation-group String N/A 在同名activation-group中的規(guī)則將以互斥的方式激發(fā)
          dialect String "java" or "mvel" 指定在LHS代碼表達式或RHS代碼塊中使用的語言。
          date-effective String, 包含日期/時間定義 N/A 規(guī)則只能在date-effective指定的日期和時間之后激活。
          date-exptires String, 包含日期/時間定義 N/A 如果當(dāng)前時間在date-expires指定的時間之后,規(guī)則不能激活。

          duration long N/A 指出規(guī)則將在指定的一段時間后激發(fā),如果那個時候規(guī)則的激活條件還是處于true的情況下。
          ⑥  LHS (when) 條件元素
          為了能夠引用匹配的對象,使用一個模式綁定變量如‘$c’。變量的前綴使用的$是可選的,但是在復(fù)雜的規(guī)則中它會很方便用來區(qū)別變量與字段的不同。
          $c : Cheese( type == "stilton", price < 10, age == "mature" )
          && 和|| 約束連接符
          Cheese( type == "stilton" && price < 10, age == "mature" )
          Cheese( type == "stilton" || price < 10, age == "mature" )
          第一個有兩個約束而第二個組有一個約束,可以通過圓括號來改變求值的順序。
          單值約束
          Matches 操作
          Cheese( type matches "(Buffalo)?\S*Mozerella" )
          Cheese( type not matches "(Buffulo)?\S*Mozerella" )
          Contains 操作
          CheeseCounter( cheeses contains "stilton" )
          CheeseCounter( cheeses not contains "cheddar" )
          memberof操作
          CheeseCounter( cheese memberof $matureCheeses )
          CheeseCounter( cheese not memberof $matureCheeses )
          字符串約束
          字符串約束是最簡單的約束格式,將字段與指定的字符串求值:數(shù)值,日期,string或者boolean。
          Cheese( quantity == 5 )
          Cheese( bestBefore < "27-Oct-2007" )
          Cheese( type == "stilton" )
          Cheese( smelly == true )
          綁定變量約束
          變量可以綁定到Fact和它們的字段,然后在后面的字段約束中使用。綁定變量被稱為聲明。有效的操作符由被約束的字段類型決定;在那里會進行強制轉(zhuǎn)換。綁定變量約束使用'=='操作符,因為能夠使用hash索引,因此提供非??斓膱?zhí)行速度。
          Person( likes : favouriteCheese )
          Cheese( type == likes )
          返回值約束
          返回值約束可以使用任何有效的Java元數(shù)據(jù)類型或?qū)ο?。要避免使用任何Drools關(guān)鍵字作為聲明標(biāo)識。在返回值約束中使用的函數(shù)必須返回靜態(tài)常量(time constant)結(jié)果。之前聲明的綁定可以用在表達式中。
          Person( girlAge : age, sex == "F" )
          Person( age == ( girlAge + 2) ), sex == 'M' )
          復(fù)合值約束
          復(fù)合值約束用在可能有多個允許值的時候,當(dāng)前只支持'in' 和'not in'兩個操作。這些操作使用圓括號包含用逗號分開的值的列表,它可以是變量,字符串,返回值或限定標(biāo)識符。'in' 和'not in'運算式實際上被語法分析器重寫成多個!= and ==組成的多重約束。
          Person( $cheese : favouriteCheese )
          Cheese( type in ( "stilton", "cheddar", $cheese )
          多重約束
          多重約束允許你對一個字段通過使用'&&' 或者'||'約束連接符進行多個約束條件的判斷。允許使用圓括號分組,它會讓這種約束看起來更自然。
          Person( age ( (> 30 && < 40) || (> 20 && < 25) ) )
          Person( age > 30 && < 40 || location == "london" )
          內(nèi)聯(lián)的Eval約束
          eval約束可以使用任何有效的語言表達式,只要它最終能被求值為boolean元數(shù)據(jù)類型。表達式必須是靜態(tài)常量(time constant)。任何在當(dāng)前模式之前定義的變量都可以使用,自動代入(autovivification)機制用來自動建立字段綁定變量。當(dāng)構(gòu)建器發(fā)現(xiàn)標(biāo)識不是當(dāng)前定義的變量名是,它將嘗試將它作為對象的字段來訪問,這種情況下,構(gòu)建器自動在inline-eval中建立該字段的同名變量。
          Person( girlAge : age, sex = "F" )
          Person( eval( girlAge == boyAge + 2 ), sex = 'M' )

          ⑦RHS (then) 執(zhí)行操作
          這部分應(yīng)當(dāng)包含一系列需要執(zhí)行的操作。規(guī)則的RHS部分應(yīng)該保持簡短的,這保持它是聲明性和可讀性的。如果你發(fā)現(xiàn)你需要在RHS中使用命令式或and/or條件代碼,那你可能需要將規(guī)則拆分為多個規(guī)則。RHS的主要目的是插入,刪除修改working memory數(shù)據(jù)。
          "update(object, handle);" 將告訴引擎對象已經(jīng)改變(已經(jīng)被綁定到LHS中的那一個),并且規(guī)則需要重新檢查。
          "insert(new Something());" 將在working memory中放置一個你新建的對象。
          "insertLogical(new Something());" 與insert類似,但是當(dāng)沒有更多的fact支持當(dāng)前激發(fā)規(guī)則的真值狀態(tài)時,對象自動刪除。
          "retract(handle);" removes an object from working memory.
          ⑧ Query
          查詢中僅僅包含規(guī)則LHS部分的結(jié)構(gòu)(不用指定when或then)。它提供了查詢working memory 中符合約束條件的對象的一個簡單辦法。
          query "people over the age of 30"
              person : Person( age > 30 )
          end
          通過在返回的查詢結(jié)果(QueryResults)上進行標(biāo)準(zhǔn)的for循環(huán)遍歷,每一行將返回一個QueryResult,該對象可以用來存取組元中的每一個Column。這些Column可以通過聲明的名稱或索引位置存取。
          QueryResults results = workingMemory.getQueryResults( "people over the age of 30" );
          for ( Iterator it = results.iterator; it.hasNext(); ) {
              QueryResult result = ( QueryResult ) it.next();
              Person person = ( Person ) result.get( "person" );
              }

           



          -------------------------------------------------------------------------------------------------
          PS:本博客文章,如果沒有注明是有“轉(zhuǎn)”字樣,屬于本人原創(chuàng)。如果需要轉(zhuǎn)載,務(wù)必注明作者文章的詳細出處地址,否則不允許轉(zhuǎn)載,多謝合作!
          posted on 2010-01-17 21:11 apple0668 閱讀(4275) 評論(0)  編輯  收藏 所屬分類: drools

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 潮州市| 潼关县| 周宁县| 石首市| 奉新县| 顺平县| 三门县| 衡山县| 武隆县| 徐水县| 天津市| 壶关县| 桃园县| 桐梓县| 常熟市| 北票市| 黎平县| 福安市| 囊谦县| 揭东县| 永年县| 江门市| 宿迁市| 永寿县| 江源县| 浪卡子县| 利津县| 米泉市| 涞水县| 修文县| 博客| 保德县| 胶州市| 舒城县| 龙州县| 延津县| 连城县| 行唐县| 图片| 靖西县| 闽侯县|