Drool是jboss的規則引擎, 老早就想看看了, 前斷時間忙的一直沒有時間.現在抽空學習一下.記錄一下學習的心得體會, 也算給今年一個交代.
是
一. 環境配置.
最快的方法:
下載Drool的eclipse外掛程式:
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 "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
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.
以下是drools提供的demo, 稍微整理了下, 可直接在eclipse中import進來
http://lcllcl987.javaeye.com/blog/255404
(前提: 下載並安裝Drool的eclipse外掛程式:Drools 4.0.7 Eclipse Workbench for 3.2 )
建議首先看看:
FibonacciExample: Fibonacci數列的drools實現.
GolfingExample: 著名的golf智力問題的drools實現,golf.drl的注釋就是此問題的文字描述.
ShoppingExample: 一個shopping打折的demo, 超過100元, 有10元的折扣.
StateExampleUsingAgendGroup: By setting dynamic to TRUE, Drools will use JavaBean, PropertyChangeListeners so you don't have to call update().
StateExampleWithDynamicRules: 動態載入rule的一個demo(載入StateExampleUsingSalience.drl後在載入StateExampleDynamicRule.drl).
TroubleTicketExample:
使用了duration規則特性: 將指定的規則延遲一定時間運行
規則引擎是在另外一個線程中進行的,因此使用了duration特性可以將指定的規則延遲一定時間運行.
但是要注意的是主線程中也需要做相應的延時,否則主線程結束後不會再處理子線程的結果
salience 和 duration特性影響rule的執行順序.
其次demo還定義了一個rule function.