JBoss Rulesサンプルプログラム

サンプルプログラムの実行結果

旅費規程のサンプルプログラム

ここでは、JBoss Rules を用いた小さなサンプルプログラムを作成します。
(この例題は、drools 2.xで作成したプログラム例題と同じです)

サラリーマンなぞをやっていると、出張の際に旅費規程というものにお世話になることもあるかと思います。出張の際の日当の種類などが定められており、例え ば出張の時間によって、日当の金額がランク別に定められているアレです。簡単ですが、この旅費規程に基づいた日当計算プログラムを作ってみましょう。

旅費規程

1日の出張時間が、4時間未満のとき 日当なし。
4時間以上、8時間未満のとき日当Cで1000円。
8時間以上、12時間未満のとき日当Bで2000円。
12時間以上のとき日当Aで3000円。

という旅費規程があったとします。

これをJBoss rulesのルールの表現形式に落としたルールファイルが、後述のsample.drlとなります。

が、まずsample.drlを説明する前に、若干の準備をしましょう。 JBoss rulesでは、ルールのプログラムは.drlファイルに書きます。 ルールの操作対象となる「もの」(ワーキングメモリの要素)を、Javaの クラスのインスタンスで表現します。 上のサンプルプログラムにおいて、ルールの操作対象となるのは、「出張」という事象です。BusinessTripというクラスを作っておきましょう。

BusinessTrip.java

package com.sample;

public class BusinessTrip {
      private String name;
      private double hour;
     
      public BusinessTrip(String name,double hour){
        this.name = name;
        this.hour  = hour;
      }
       
      public String getName(){
        return name;
      }
     
      public double getHour(){
        return hour;
      }
}

さらに、メインプログラムでは、ルールベースエンジンを動かす環境設定、ワーキングメモリへの「出張」インスタンスの書き込み、ルールベースエンジンの実行を行います。

DroolsTest.java

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;

public class DroolsTest {
    public static final void main(String[] args) {
        try {
           
            RuleBase ruleBase = readRule();

            WorkingMemory workingMemory = ruleBase.newWorkingMemory();
           
            workingMemory.assertObject(new BusinessTrip(“野中”,3.5));
      workingMemory.fireAllRules();

      workingMemory.assertObject(new BusinessTrip(“大前”,5.0));
            workingMemory.fireAllRules();

            workingMemory.assertObject(new BusinessTrip(“米倉”,8.0));
            workingMemory.fireAllRules();

            workingMemory.assertObject(new BusinessTrip(“嶋口”,10.0));
            workingMemory.fireAllRules();

            workingMemory.assertObject(new BusinessTrip(“伊丹”,13.0));
            workingMemory.fireAllRules();

            } catch (Throwable t) {

                t.printStackTrace();

            }

    }

private static RuleBase readRule() throws Exception {

        Reader source = new InputStreamReader(
                        DroolsTest.class.getResourceAsStream( “/Sample.drl” ) );
        PackageBuilder builder = new PackageBuilder();
        builder.addPackageFromDrl( source );
        Package pkg = builder.getPackage();
        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
        ruleBase.addPackage( pkg );
        return ruleBase;

    }

}

 まず、sample.drlのルールを読み込み、ワーキングメモリを作成。次に
ワーキングメモリの要素を書き込んでは、ルールを実行(ルールのfire-発火-)、
書き込んでは、ルールを実行・・・を繰り返しています。
(ワーキングメモリに一度に全部を書き込んで、最後にまとめてルールの実行をしても結果は同じです
-正確に言うと、表示順は変わってくる可能性があります-)

ビジネスの実際のアプリケーションとなると、これらのインスタンスの情報はデータベースから読み込むとか、画面からユーザが手で入れるということになりますが、今回はサンプルプログラムということで、簡単のためにメインプログラムにハードコーディングをしてしまいました。

さらに、最後に肝心のルールプログラム

sample.drl

package com.sample

import com.sample.BusinessTrip

rule “日当なし”
    when
        bt : BusinessTrip( hour <4.0 , name : name )
    then
        System.out.println( name +”さんの出張時間は、”
        + bt.getHour() +”時間なので、日当はありません。 (ルール:日当なし)”);
end

rule “日当C”
    when
        bt : BusinessTrip( hour >= 4.0 , hour < 8.0 , name : name )
    then
        System.out.println( name +”さんの出張時間は、”
        +bt.getHour()+”時間なので、日当は1000円です。(ルール:日当C)”);
end

rule “日当B”
    when
        bt : BusinessTrip( hour >= 8.0 , hour < 12.0 , name : name )
    then
        System.out.println( name +”さんの出張時間は、”
        +bt.getHour()+”時間なので、日当は2000円です。(ルール:日当B)”);
end
 
rule “日当A”
    when
        bt : BusinessTrip( hour >= 12.0 , name : name )
    then
        System.out.println( name +”さんの出張時間は、”
        +bt.getHour()+”時間なので、日当は3000円です。(ルール:日当A)”);
end

 これを実行すると

 サンプルプログラムの実行結果

となります。