Droolsの練習の一環として、国税庁のサイトの所得税率のページを見ながら、以下のようなルール定義ファイルを書いてみた。
package com.sample function long trunc1000(long value) { return value / 1000 * 1000; } function long zeigaku(long shotoku, int zeiritsu, int kojo) { return trunc1000(shotoku) * zeiritsu / 100 - kojo; } function boolean inRange(long shotoku, long lower, long upper) { return lower < shotoku && shotoku <= upper; } function void print(long shotoku, int zeiritsu, int kojo) { System.out.println( String.format("所得:%1$,10d -> 税額:%2$,9d", shotoku, zeigaku(shotoku, zeiritsu, kojo))); } rule "195万円以下" when $shotoku: Shotoku(name == "所得", $v: value) eval (trunc1000($v)<=1950000) then print($v, 5, 0); end rule "330万円以下" when $shotoku: Shotoku(name == "所得", $v: value) eval (inRange(trunc1000($v), 1950000, 3300000)) then print($v, 10, 97500); end rule "695万円以下" when Shotoku(name == "所得", $v:value) eval (inRange(trunc1000($v), 3300000, 6950000)) then print($v, 20, 427500); end rule "900万円以下" when Shotoku(name == "所得", $v:value) eval (inRange(trunc1000($v), 6950000, 9000000)) then print($v, 23, 636000); end rule "1800万円以下" when Shotoku(name == "所得", $v:value) eval (inRange(trunc1000($v), 9000000, 18000000)) then print($v, 33, 1536000); end rule "1800万円超" when Shotoku(name == "所得", $v:value) eval(trunc1000($v) > 18000000) then print($v, 40, 2796000); endこれを以下のようなJava コードで実行してみると・・・
private static void insertShotoku(WorkingMemory wm, long shotoku) { wm.insert(new Shotoku(shotoku)); } public static final void main(String[] args) { try { ・・・略 WorkingMemory wm = ruleBase.newStatefulSession(); insertShotoku(wm, 1000000); insertShotoku(wm, 1950000); insertShotoku(wm, 1950999); insertShotoku(wm, 1951000); insertShotoku(wm, 3300000); insertShotoku(wm, 6950000); insertShotoku(wm, 9000000); insertShotoku(wm, 18000000); insertShotoku(wm, 18001000); wm.fireAllRules(); ・・・略次のようなコンソール出力を得る
所得:18,001,000 -> 税額: 4,404,400 所得:18,000,000 -> 税額: 4,404,000 所得: 9,000,000 -> 税額: 1,434,000 所得: 6,950,000 -> 税額: 962,500 所得: 3,300,000 -> 税額: 232,500 所得: 1,951,000 -> 税額: 97,600 所得: 1,950,999 -> 税額: 97,500 所得: 1,950,000 -> 税額: 97,500 所得: 1,000,000 -> 税額: 50,000出てきた税額はまずまず合ってるっぽい。
上で使った税率は平成21年度現在のものだけど、同サイトでは平成18年以前の速算表も載っている。やはり、こういった税率やらを含む制度はしょっちゅう変わるわけで、こんなのをいちいち Javaソースにハードコードするのも馬鹿馬鹿しい。ルールはルールで別途外部のリソースとして置いて、実行時に読み込むような形にするべきなんだろうと思う。
ところで、理想的にはユーザ側のドメインエキスパートがルール定義ファイルを書くのが良いと思うのだけど、どの程度こういった DSL に対応できるのだろう・・・?個人差はあるだろうけど、まったくのプログラム未経験のビジネスパーソンには、ちょっと難しいような気もする。
それと、自分が Drools を触り始めたばかりで、まだまだ良く分かっていないという事もあるのだろうけど、どうもいまいち Java コードとルール定義がスッキリ分離しきれない気がする。Javaコードを書くプログラマとルールを定義するビジネスパーソンの間で、上手いこと住み分けと協調をやってかないと、かえって面倒くさい事になりそうな気がしないでもない。何か評価の定まったベストプラクティス的なものがあればいいんだけど。
0 件のコメント:
コメントを投稿