whenとthen

まずはシンプルに動かしてみます。Jumperというクラスにstepというintのフィールドを持たせます。意味合いとしては0:start,1:hop,2:step,3:jumpにします。0で始めたらhopしなさい、hopしたらstepにしなさい、stepしたらjumpやろー!というのを簡単にJavaで書きます。

Jumper jumper = new Jumper();
for (int i = 0; i < 3; i++) {
  if (jumper.getStep()==0) {
    jumper.setStep(1);
    System.out.println("Hop!!");
  } else if (i == 1) {
    jumper.setStep(2);
    System.out.println("Step!!");				
  } else if (i == 2) {
    jumper.setStep(3);
    System.out.println("Jump!!");				
  } else {
    System.out.println("NG!!");								
}

クラス設計次第で多少変わりますが(stepの遷移をJumperの中に書いてもいいのですが、それこそいろんな書き方ができてしまう、といういい例かもと思いつつ)まずこんな感じですね。大事なのは"3"というのをしってること。hop,step,jumpの飛び方を知ってることを前提にこう書けます。実行すれば、Hop!!,Step!!,Jump!!とコンソールにでます。
一方、Droolsではこう書きます。

package com.sample

import com.sample.Jumper;
 
rule "hop"
  when
    $j : Jumper( step == 0 );
  then
    System.out.println( "Hop!!" ); 
    $j.setStep( 1 );
    update( $j );
end

rule "step"
  when
    $j : Jumper( step == 1 );
  then
    System.out.println( "Step!!" ); 
    $j.setStep( 2 );
    update( $j );
end

rule "jump"
  when
    $j : Jumper( step == 2 );
  then
    System.out.println( "Jump!!" ); 
    $j.setStep( 3 );
    update( $j );
end

で、メイン処理はこれ。

public class JumpRuleTest {

  public static final void main(String[] args) {
    // ルール読み込み
    KnowledgeBase kbase = readKnowledgeBase();
		
    // 実際のメイン処理はこの4行
    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
    Jumper jumper = new Jumper();
    ksession.insert(jumper);
    ksession.fireAllRules();
  }

  private static KnowledgeBase readKnowledgeBase() {
			
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newClassPathResource("jump.drl"), ResourceType.DRL);
    KnowledgeBuilderErrors errors = kbuilder.getErrors();
    if (errors.size() > 0) {
      for (KnowledgeBuilderError error: errors) {
        System.err.println(error);
      }
      throw new IllegalArgumentException("Could not parse knowledge.");
    }
    
    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    return kbase;
  }
}

これを実行すると同じようにHop!Step!Jump!とコンソール表示できますよ、と。本番ではルールは基本的にプレコンパイルしておくはずなのでルール読み込み部分(privateメソッド含む)は、まぁ置いておきます。ルールの中もDroolsゆえの記述があるもののwhenとthenのみの宣言的な記述ができるわけです。はじめの1歩なのでシンプルに書きます。で、ここからルールが複雑になればなるほどdrools冥利につきます。