ApplicationData(アプリケーションデータ)について
droolsの機能として、Application Dataという機能があります。通常、droolsを用いてルールを用いたプログラムを作ろうとする場合、ルール部分(ルールベース、ワーキングメモリ、ルールエンジン)とJava本体プログラムとのやりとりは、本体でのインスタンスを fact としてワーキングメモリに assert し、そこを通じて行うことになります。
しかし、実際のプログラミングを行っていると、ルールの記述の中で、例えば、「数値の比較部分で、ちょっとJava本体のプログラムで行った計算結果を使いたい。」などという場合や、「GUIの画面に直接結果を表示したい」などという場合が出てきます。こういったときに、いちいち fact を assert して云々というのもかなり煩わしいものでしょう。Application Dataは、このようにルールの条件部のパラメータとして、本体プログラムの結果をちょっと参照したいとか、GUIの画面に結果を直接表示したいというようなときに威力を発揮します。
使い方としては、
ルールの記述ファイル(.drl)に
<application-data identifier=”amount”>java.lang.Integer</application-data>
(amountがルールファイルの中で参照する識別子、java.lang.Integerが、amountのデータ型)
と宣言することで、まずルールの条件部(condition部)、結果部(consequence部)でamountという識別子を使うことができるようになります。(例は、droolsページのApplication Data の項からとっています)
この上さらに本体のプログラムのほうで、
workingMemory.setApplicationData(“amount”,new Integer(3));
と記述することによって、ルールの記述ファイルの中での識別子amountに対して、実体が与えられるということになります(ちなみに基本データ型については、上記のようにラッパを使う必要があります)。
それでは、実際のプログラムとして、JavaのSWTで入出力画面を作って、出張日当の計算のプログラムにかぶせてみましょう。ここでは、Application Dataの例として、ごく簡単に作ってみました(入力チェックなども行っていません)。
BusinessTrip.javaは、droolsのサンプルプログラムで作成したプログラムと同じ(パッケージ名は変えています)ですが、mainプログラムとsample.drlが若干記述が変わってきます。(mainプログラムについては、EclipseのVisualEditorを使って書くのが最も簡単と思います。)
BtripSample.java(メインプログラム:太字の部分は、VisualEditorで自動生成したプログラムに後から加えたもしくは修正した部分)
package drools.example.applidata;
import org.drools.RuleBase; public class BtripSample { private Shell sShell = null; public static void main(String[] args) { try { private void createSShell() { public void textDisplay(String str) { |
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.applidata.BusinessTrip</java:import> <java:import>drools.example.applidata.BtripSample</java:import> <application-data identifier=”frame”>BtripSample</application-data> <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()+”時間なので、日当はありません。 (ルール:日当なし)”); frame.textDisplay(btrip.getName()+”さんの出張時間は、” +String.valueOf(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)”); frame.textDisplay(btrip.getName()+”さんの出張時間は、” +String.valueOf(btrip.getHour())+”時間なので、日当は1000円です。 (ルール:日当C)”); </java:consequence> </rule> <rule name=”日当B”> <rule name=”日当A”> </rule-set> |
これを動かすと、下記のようになります。