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

          首先我們要取得rule,規(guī)則引擎、規(guī)則引擎,取得規(guī)則是必要的。
          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;
          ????}

          這里在官方的例子基礎(chǔ)上做了自己的實(shí)現(xiàn)(其實(shí)什么都沒(méi)改)。

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

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

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

          接下來(lái)看看怎么執(zhí)行它:
          ????????????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生成一個(gè)WorkingMemory,WorkingMemory是Rule的執(zhí)行引擎,裝載rule和事實(shí)(很重要的概念),并統(tǒng)一執(zhí)行他們。接下來(lái)我就在寫我的事實(shí),事實(shí)是什么,事實(shí)就是今天是什么天?訂單總價(jià)多少?就是要告訴腳本的java對(duì)象。然后把事實(shí)一一壓入WorkingMemory這個(gè)大壓縮機(jī)。就瞧好吧。

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

          ???究竟執(zhí)行了什么。當(dāng)然是執(zhí)行了我們的腳本,腳本在這里、看看它可不是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

          每一個(gè)rule就是一個(gè)規(guī)則,所有的事實(shí)要一一過(guò)一遍這些規(guī)則。when是規(guī)則提出的條件,如果哪個(gè)事實(shí)符合這個(gè)條件,就進(jìn)入then的環(huán)節(jié),進(jìn)行相應(yīng)的處理。

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

          這樣走完一個(gè)rule后大家很容易發(fā)現(xiàn),其實(shí)是根據(jù)訂單和用戶的角色不同產(chǎn)生了不同的acl,然后我要拿到這些由事實(shí)得到的事實(shí)。

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

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

          FeedBack:
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2006-05-28 22:46 | 艾塵
          開(kāi)始接觸Drools。一起學(xué)習(xí)! :)  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2006-05-28 23:54 | 差沙
          我是剛剛開(kāi)始,以后多交流。對(duì)了,你要用在什么場(chǎng)合?  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2006-05-29 21:20 | C[ETI]O@quaffsoft
          $userName : name
          表示什么意思?把user的name屬性值賦給userName變量?  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          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());  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2006-05-29 22:28 | 差沙
          @C[ETI]O@quaffsoft
          正解  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2006-05-30 22:15 | C[ETI]O@quaffsoft
          如何判斷一個(gè)Integer?比如要判斷一個(gè)大于10的Integer
          $integer:Integer(),括號(hào)里面怎么寫,,目前的做法是寫一個(gè)類弄個(gè)Integer類型屬性
            回復(fù)  更多評(píng)論
            
          # xuxqqhyo
          2007-06-15 05:35 | xuxqqhyo
          dbdwwyon http://lvunjlvs.com llokaulb gtskgzvt  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2008-04-22 14:02 | javapon
          你好~最近正學(xué)Drools呢~可網(wǎng)上的資料并不是很多,特別是.dsl文件網(wǎng)上大部分多是XML文件格式的那種~~~~你有相關(guān)的資料嗎?或關(guān)于Drools的小編程~~~~望能發(fā)一份給我~~~謝謝了。郵箱 javapon@163.com  回復(fù)  更多評(píng)論
            
          # re: 關(guān)于Drools的初步,迷醉狀態(tài)認(rèn)識(shí)
          2008-04-22 14:05 | javapon
          @@本來(lái)以為網(wǎng)上應(yīng)該有不少的講解了,但是發(fā)現(xiàn)幾乎全是針對(duì)2.0版本講解的.
          恩對(duì)找了老半天也找不到新版本的講解~~~~  回復(fù)  更多評(píng)論
            
          這家伙很懶,但起碼還是寫了一句話。

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

          常用鏈接

          留言簿(8)

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 陵水| 平陆县| 罗江县| 昂仁县| 张家港市| 宣威市| 长兴县| 大足县| 盖州市| 凉城县| 衡东县| 陇川县| 哈巴河县| 湄潭县| 酉阳| 湟中县| 革吉县| 镇坪县| 琼结县| 旬邑县| 藁城市| 乌拉特后旗| 千阳县| 泸溪县| 开封县| 长乐市| 涟水县| 礼泉县| 博兴县| 青州市| 喀喇| 米林县| 巴林右旗| 綦江县| 黄梅县| 会宁县| 来宾市| 临桂县| 丁青县| 祥云县| 宁陕县|