Drools學習(一)

iteye_6308發表於2008-10-17


Drool是jboss的規則引擎, 老早就想看看了, 前斷時間忙的一直沒有時間.現在抽空學習一下

什麼是規則引擎, rete演算法等等就交給google了.

鄙人是實幹家.
一. 環境配置.
最快的方法:
下載Drool的eclipse外掛:Drools 4.0.7 Eclipse Workbench for 3.2
http://www.jboss.org/drools/downloads.html

此外掛功能不錯, 寫rule很方便, 並且能建立 drool project, 所有依賴的jar包都有包含.

 二: hello world
晦澀的理論先放一邊, 跑一個hello world再說:

package com.sample;

import java.io.InputStreamReader;
import java.io.Reader;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;

/**
 * This is a sample file to launch a rule package from a rule source file.
 */
public class DroolsTest {

    public static final void main(String[] args) {
        try {
           
            //load up the rulebase
            RuleBase ruleBase = readRule();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();
           
            //go !
            Message message = new Message();
            message.setMessage(  "Hello World" );
            message.setStatus( Message.HELLO );
            workingMemory.insert( message );
            workingMemory.fireAllRules();  
           
           
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /**
     * Please note that this is the "low level" rule assembly API.
     */
    private static RuleBase readRule() throws Exception {
        //read in the source
        Reader source = new InputStreamReader( DroolsTest.class.getResourceAsStream( "/Sample.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;
    }
   
    public static class Message {
        public static final int HELLO = 0;
        public static final int GOODBYE = 1;
        public static final int GAME_OVER = 2;
       
        private String message;
       
        private int status;
       
        public String getMessage() {
            return this.message;
        }
       
        public void setMessage(String message) {
            this.message = message;
        }
       
        public int getStatus() {
            return this.status;
        }
       
        public void setStatus( int status ) {
            this.status = status;
        }
    }
   
}
 


rule檔案:
   Sample.drl

package com.sample
 
import com.sample.DroolsTest.Message;
 
rule "Hello World"
    when
        m : Message( status == Message.HELLO, message : message )
    then
        System.out.println( message );
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "GoodBye"
    no-loop true
    when
        m : Message( status == Message.GOODBYE, message : message )
    then
        System.out.println( message );
        m.setStatus(Message.GAME_OVER);
        m.setMessage("game over now!");   
        update( m );   
end

rule "game over"
    when
        m : Message( status == Message.GAME_OVER)
    then
        System.out.println( m.getMessage() );        
end
 


java程式碼就不說了, 主要說明一下rule檔案, 藉此熟悉一下rule語法:
1:規則的主體結構:
rule "name"
    ATTRIBUTES
    when
        LHS
    then
        RHS
end

其中:
LHS(left hand side)是規則的條件部分, RHS(right hand side)是條件滿足後的自行塊.

2: 條件的書寫:
m : Message( status == Message.HELLO, message : message )
意思是:
在working Memory中, 如果有一個Message的instance滿足如下條件:
它的status屬性等於Message.HELLO.
滿足條件的Message instance 用變數 m表示, 它的message屬性用message變數表示, 以便在RHS中使用.
 
3: 條件滿足後的自行塊(RHS)

         System.out.println( message );
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
 

用到了在LHS中 定義的變數: m, message
update( m )表示把此Message instance在 working memory中更新.這便會觸發名稱為"GoodBye"的rule, 進而觸發名稱為"game over"的rule.

今天就到這裡吧.

下課!

相關文章