droolsサンプルプログラム

実行結果

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

ここでは、droolsを用いた小さなサンプルプログラムを作成します。

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

旅費規程
1日の出張時間が、4時間未満のとき 日当なし。
4時間以上、8時間未満のとき日当Cで1000円。
8時間以上、12時間未満のとき日当Bで2000円。
12時間以上のとき日当Aで3000円。
という旅費規程があったとします。

これをif-thenの形のルールで書くと

if 1日の出張時間 < 4.0時間 then 日当なし。
if 4.0時間 <= 1日の出張時間 < 8.0時間 then 日当C:1000円。
if 8.0時間 <= 1日の出張時間 < 12.0時間 then 日当B:2000円。
if 12.0時間 <= 1日の出張時間 then 日当A:3000円。

これをさらにdroolsの表現形式に落としたのが、後述のsample.drlとなります。

が、まずsample.drlを説明する前に、若干の準備をしましょう。

droolsでは、ルールのプログラムはxml形式で、.drlファイルに書きます。
ルールの操作対象となる「もの」(ワーキングメモリの要素)を、Javaの
クラスのインスタンスで表現します。

上のサンプルプログラムにおいて、ルールの操作対象となるのは、「出張」という事象です。BusinessTripというクラスを作っておきましょう。

BusinessTrip.java

 package drools.example.sample1;

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;
      }
}

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

DroolsExample.java

package drools.example.sample1;

import org.drools.RuleBase;
import org.drools.WorkingMemory;
import org.drools.io.RuleBaseLoader;

public class DroolsExample {

    public static void main(String[] args) throws Exception  {
        RuleBase ruleBase = RuleBaseLoader.loadFromUrl(
                  DroolsExample.class.getResource(“sample.drl”) );
               
        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();
    }

}

 

 まず、sample.drlのルールを読み込み、ワーキングメモリを作成。次に
ワーキングメモリの要素を書き込んでは、ルールを実行(ルールのfire-発火-)、
書き込んでは、ルールを実行・・・を繰り返しています。
(ワーキングメモリに一度に全部を書き込んで、最後にまとめてルールの実行をしても結果は同じです)

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

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

sample.drl

 <?xml version=”1.0″ encoding=”UTF-8″?>
<rule-set name=”daily allowance”
          xmlns=”http://drools.org/rules”
          xmlns:java=”http://drools.org/semantics/java”
          xmlns:xs=”http://www.w3.org/2001/XMLSchema-instance”
          xs:schemaLocation=”http://drools.org/rules rules.xsd
                             http://drools.org/semantics/java java.xsd”>
 
  <java:import>drools.example.sample1.BusinessTrip</java:import>
 
  <rule name=”日当なし”>
    <parameter identifier=”btrip”>
      <class>BusinessTrip</class>
    </parameter>
    <java:condition>btrip.getHour() < 4.0</java:condition>
    <java:consequence>
      System.out.println(btrip.getName()+”さんの出張時間は、”
    +btrip.getHour()+”時間なので、日当はありません。 (ルール:日当なし)”);
    </java:consequence>
  </rule>
 
  <rule name=”日当C”>
    <parameter identifier=”btrip”>
      <class>BusinessTrip</class>
    </parameter>
    <java:condition>4.0 <= btrip.getHour()</java:condition>
    <java:condition>btrip.getHour() < 8.0</java:condition>
    <java:consequence>
      System.out.println(btrip.getName()+”さんの出張時間は、”
    +btrip.getHour()+”時間なので、日当は1000円です。 (ルール:日当C)”);
    </java:consequence>
  </rule>

  <rule name=”日当B”>
    <parameter identifier=”btrip”>
      <class>BusinessTrip</class>
    </parameter>
    <java:condition>8.0 <= btrip.getHour()</java:condition>
    <java:condition>btrip.getHour() < 12.0</java:condition>
    <java:consequence>
      System.out.println(btrip.getName()+”さんの出張時間は、”
    +btrip.getHour()+”時間なので、日当は2000円です。 (ルール:日当B)”);
    </java:consequence>
  </rule>

  <rule name=”日当A”>
    <parameter identifier=”btrip”>
      <class>BusinessTrip</class>
    </parameter>
    <java:condition>12.0 <= btrip.getHour()</java:condition>
    <java:consequence>
      System.out.println(btrip.getName()+”さんの出張時間は、”
    +btrip.getHour()+”時間なので、日当は3000円です。 (ルール:日当A)”);
    </java:consequence>
  </rule>

</rule-set>
 

 これを実行すると

 実行結果

となります。