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.
今天就到这里吧.
下课!