Re:出張旅費規定

例外規定を含め日当を算出する処理をDroolsで実装してみた。ただしあくまでも「理解できる範囲」で「曖昧」「理解不能」な部分はskip。プログラミング演習の課題としJavaでもVB.NETでもなんでもいいから、

出張旅費規定で定められた日当を算出するプログラムを作成せよ

というのを出したら作成した人の数だけ異なる結果になりそうで怖いw。その位?な部分がある規定もどうかと思う。

まぁそれは置いといて、作成したルールは16個、drlファイルは160行くらい(コメント行、空行を除く)。この時点で「Droolsのメリットって何さ?」と聞かれたら次の2点かね。

  • ループで処理を回さなくてイイ
  • 条件検索が多少楽に書ける

前者はDroolsがルールに一致するfactを探して処理して、該当が無くなれば終了(呼び出し元へ返る)。乱暴に言えば「ガラガラポン」。後者は、たとえば「休日に、4時間以上乗車していたら、2,000円支給する。ただし管理職は除く」という場合、Droolsではこんな感じにしてみた。

rule "HOLIDAY_TRAVELING"
  when
    $member : Member(manager == false, $id : id)
    $detail : Detail(travelingHr >= 4.0,
                           UtilsDate.isHoliday(date) == true,
                            id == $id,
                           $seqno : seqno, $date : date)
  then
    insert(new Payment($id, $seqno, $date, Payment.HOLIDAY, 2000));
end

whenが条件だけど、これをSQLで書くとこんな感じかな。

SELECT Member.id, Detail.seqno, Detail.date
  FROM MEMBER, DETAIL
 WHERE Member.id = Detail.id
   AND Member.manager = false
   AND Detail.travelingHr >= 4.0
   AND Detail.date IN (休日リスト)

データというかfactにリレーションを意識した属性を持たせておけばSELECT文のような感覚で条件を書ける。考え方としてはHibernateみたいなオブジェクト関係マッピング (ORM)。これをふつーのJavaで書いたらどうなる?MemberとDetailがArrayListならfor-eachの二重ループにして、...。結構面倒かも。それをすぱっとSQL的な発想で書けるので楽といえば楽。 しかしこれだけでは「Droolsで行こう」ということにはならんけどね。