差沙的密碼 -- SSHWSFC's code
          閱讀本Blog請自備塑料袋一只
          posts - 14,  comments - 59,  trackbacks - 0
          這兩天在springside受白衣的影響開始關注drools。說他是平民的腳本引擎一點都不假,使用起來極為方便,本來以為網上應該有不少的講解了,但是發現幾乎全是針對2.0版本講解的。而drools加入jboss后有了質的變化,下面來看一下最新的3.0使用起來有什么不同:

          首先我們要取得rule,規則引擎、規則引擎,取得規則是必要的。
          private?static?RuleBase?readRule()?throws?Exception?{
          ????????
          //read?in?the?source
          ????????Reader?source?=?new?InputStreamReader(?DroolsTest.class.getResourceAsStream(?"/aclcreat.drl"?)?);
          ????????
          ????????
          //optionally?read?in?the?DSL?(if?you?are?using?it).
          ????????Reader?dsl?=?new?InputStreamReader(?DroolsTest.class.getResourceAsStream(?"/mylang.dsl"?)?);

          ????????
          //Use?package?builder?to?build?up?a?rule?package.
          ????????
          //An?alternative?lower?level?class?called?"DrlParser"?can?also?be?used
          ????????
          ????????PackageBuilder?builder?
          =?new?PackageBuilder();

          ????????
          //this?wil?parse?and?compile?in?one?step
          ????????
          //NOTE:?There?are?2?methods?here,?the?one?argument?one?is?for?normal?DRL.
          ????????
          //builder.addPackageFromDrl(?source?);

          ????????
          //Use?the?following?instead?of?above?if?you?are?using?a?DSL:
          ????????builder.addPackageFromDrl(?source,?dsl?);
          ????????
          ????????
          //get?the?compiled?package?(which?is?serializable)
          ????????Package?pkg?=?builder.getPackage();
          ????????
          ????????
          //add?the?package?to?a?rulebase?(deploy?the?rule?package).
          ????????RuleBase?ruleBase?=?RuleBaseFactory.newRuleBase();
          ????????ruleBase.addPackage(?pkg?);
          ????????
          return?ruleBase;
          ????}

          這里在官方的例子基礎上做了自己的實現(其實什么都沒改)。

          可以看到,第一步是取得文件IO,這個文件就是我們要寫得規則腳本,這個等下再說,大家可以假象一下腳本是個什么樣子,現在只說怎么在程序中取得Rule。
          接下來,是使用Builder取得一個package,既然builder都上來了說明能輸入的腳本不止一個了。用addPackageFromDrl向這個builder壓縮機里面輸入腳本,當然還有另外一個文件dsl,這個后面再說。利用builder取得package。

          最后構造一個BaseRule,利用Factory取得的時候是有選擇的,RuleBaseFactory.newRuleBase(int type)其中的type可以為不同的Algorithm,有RETE和Leaps 兩種。對這兩種Algorithm的具體解釋可以參看 http://citeseer.ist.psu.edu/context/505087/0?或是 drools的文檔,其實我也不太懂。

          把剛才的package添到ruleBase里面一個Rule就大功告成了。

          接下來看看怎么執行它:
          ????????????WorkingMemory?workingMemory?=?ruleBase.newWorkingMemory();
          ????????????
          ????????????
          //go?!
          ????????????Order?order?=?new?Order();
          ????????????order.setId(
          1);
          ????????????order.setName(
          "testOrder");
          ????????????order.setTotlePrice(
          10);
          ????????????????????????
          ????????????User?user?
          =?new?User();
          ????????????user.setName(
          "testAdmin");
          ????????????user.setAuth(
          "USER_ADMIN");
          ????????????List
          <String>?roles?=?new?ArrayList<String>();
          ????????????roles.add(
          "ADMIN");
          ????????????user.setRoles(roles);
          ????????????

          ????????????User?user1?
          =?new?User();
          ????????????user1.setName(
          "testUser");
          ????????????user1.setAuth(
          "USER_USER");
          ????????????List
          <String>?roles1?=?new?ArrayList<String>();
          ????????????roles1.add(
          "USER");
          ????????????user1.setRoles(roles1);
          ????????????
          ????????????workingMemory.assertObject(order);
          ????????????workingMemory.assertObject(user);
          ????????????workingMemory.assertObject(user1);
          ????????????
          ????????????workingMemory.fireAllRules();????????
          ????????????
          ????????????List
          <AclEntry>?acls?=?workingMemory.getObjects(AclEntry.class);

          用ruleBase生成一個WorkingMemory,WorkingMemory是Rule的執行引擎,裝載rule和事實(很重要的概念),并統一執行他們。接下來我就在寫我的事實,事實是什么,事實就是今天是什么天?訂單總價多少?就是要告訴腳本的java對象。然后把事實一一壓入WorkingMemory這個大壓縮機。就瞧好吧。

          OK可以執行了,fireAllRules!(真TM,COOL的名字)。當然有全部執行就有部分執行。你可以把規則分組,然后按組執行,或是指定rule的名字來執行(這里還是大家自己看看吧)。

          ???究竟執行了什么。當然是執行了我們的腳本,腳本在這里、看看它可不是xml了:
          #created?on:?2006-5-19
          package?com.sample;

          #list?any?
          import?classes?here.

          import?com.sample.domain.Order;
          import?com.sample.domain.User;

          import?com.sample.AclEntry;
          #expander?mylang.dsl

          #declare?any?global?variables?here

          rule?
          "Order?TotlePrice?more?than?$1000"????
          ????when
          ????????#conditions
          ????????$order?:?Order(?totlePrice?
          >?1000?)
          ????????$user?:?User(?roles?contains?
          "ADMIN"?,?$userName?:?name)
          ????then?
          ????????#actions
          ????????System.out.println(
          "More?Than");
          ????????
          assert(new?AclEntry($order,?$user,?1));
          end

          rule?
          "Order?TotlePrice?less?or?equl?than?$1000"????
          ????when
          ????????#conditions
          ????????$order?:?Order(?totlePrice?
          <=?1000?)
          ????????$user?:?User(?$userName?:?name?)
          ????then?
          ????????#actions
          ????????System.out.println(
          "Less?Than");
          ????????
          assert(new?AclEntry($order,?$user,?2));
          end

          每一個rule就是一個規則,所有的事實要一一過一遍這些規則。when是規則提出的條件,如果哪個事實符合這個條件,就進入then的環節,進行相應的處理。

          分析一下條件:$order?:?Order(?totlePrice?>?1000?)。一看就知道是總價超過1000的訂單。$order是把這個訂單邦定,后面可以使用。
          分析一下then:?System.out.println就不解釋了。assert(new?AclEntry($order,?$user,?2)); 這里的assert的意義就是告訴WorkingMemory一個事實,其實跟前面的加入事實一個道理。打個比方,如果有閃電,那么就有雷。

          這樣走完一個rule后大家很容易發現,其實是根據訂單和用戶的角色不同產生了不同的acl,然后我要拿到這些由事實得到的事實。

          List<AclEntry>?acls?=?workingMemory.getObjects(AclEntry.class);
          這樣就能在workingMemory里面掏出我們需要的事實來,新鮮出爐的哦。

          相當粗略的講了一下drools,目的是希望大家都來了解一下,共同學習。
          posted on 2006-05-28 20:53 差沙 閱讀(2842) 評論(9)  編輯  收藏 所屬分類: avaj

          FeedBack:
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-28 22:46 | 艾塵
          開始接觸Drools。一起學習! :)  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-28 23:54 | 差沙
          我是剛剛開始,以后多交流。對了,你要用在什么場合?  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-29 21:20 | C[ETI]O@quaffsoft
          $userName : name
          表示什么意思?把user的name屬性值賦給userName變量?  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-29 21:34 | C[ETI]O@quaffsoft
          @C[ETI]O@quaffsoft

          $userName是變量
          System.out.println("More Than 50,userName"+$userName);
          System.out.println("More Than 50,userName"+$user.getName());  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-29 22:28 | 差沙
          @C[ETI]O@quaffsoft
          正解  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2006-05-30 22:15 | C[ETI]O@quaffsoft
          如何判斷一個Integer?比如要判斷一個大于10的Integer
          $integer:Integer(),括號里面怎么寫,,目前的做法是寫一個類弄個Integer類型屬性
            回復  更多評論
            
          # xuxqqhyo
          2007-06-15 05:35 | xuxqqhyo
          dbdwwyon http://lvunjlvs.com llokaulb gtskgzvt  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2008-04-22 14:02 | javapon
          你好~最近正學Drools呢~可網上的資料并不是很多,特別是.dsl文件網上大部分多是XML文件格式的那種~~~~你有相關的資料嗎?或關于Drools的小編程~~~~望能發一份給我~~~謝謝了。郵箱 javapon@163.com  回復  更多評論
            
          # re: 關于Drools的初步,迷醉狀態認識
          2008-04-22 14:05 | javapon
          @@本來以為網上應該有不少的講解了,但是發現幾乎全是針對2.0版本講解的.
          恩對找了老半天也找不到新版本的講解~~~~  回復  更多評論
            
          這家伙很懶,但起碼還是寫了一句話。

          <2006年5月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(8)

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 兴安县| 洛宁县| 大悟县| 新竹县| 胶州市| 滨州市| 额尔古纳市| 秀山| 宜章县| 绥滨县| 色达县| 开化县| 汝阳县| 静安区| 新和县| 丘北县| 双江| 大埔县| 阿瓦提县| 花垣县| 清水河县| 军事| 兰溪市| 雅安市| 太保市| 交口县| 沁水县| 闽清县| 古丈县| 五莲县| 信阳市| 泌阳县| 浠水县| 漳平市| 钟祥市| 吕梁市| 德昌县| 蒙阴县| 襄垣县| 屏东县| 大新县|