Scala
BRMS

Scala版 BRMS ツール(Drools)を試してみた

BRMSという言葉を最近聞いた。
ビジネス・ルール・マネージメント・システムの略らしい。
こいつを適用すると、アプリと業務処理を分別することができるらしい。
確かに昔は、Javaで業務処理を書いた時はif文の嵐だったから、これを適用すれば
業務処理は、BRMSに委ねることができるので大幅に作業の効率化が図れるのは間違いなさそうだ。

今回は、RedHat提供のBRMSツール(Drools)を試してみることにする。
github

DroolsMain.scala
package jp.co.drools.droolsscalaexample

import scala.collection.mutable.ListBuffer

object DroolsMain extends App{
  println("start")

  for {
    // ローンパターン適用。autoclose してくれる inputStream系も使えるのがナイス
    hd <- Loan(HogeDecision)
  } {
    val hdb = HogeDecisionBean(101, 1, ListBuffer.empty)
    val fdb = FugaDecisionBean(2, ListBuffer.empty)
    val ret_hdb = hd.determine(hdb)
    val ret_fdb = hd.determine(fdb)

    ret_confirm(ret_hdb)
    ret_confirm(ret_fdb)

    def ret_confirm[A](facts: Decision[A]):Unit ={
      facts.get().foreach(println(_))
    }
  }

  println("end")
}

Droolsとのデータ一時格納領域
イミュータブルな性格のScalaでListBufferを使うのはちょっと抵抗あるけど、
Droolsはクラスを予めオブジェクト化する特徴があるから、しょうがないかなあ。

HogeBean.scala
package jp.co.drools.droolsscalaexample

import scala.beans.BeanInfo
import scala.collection.mutable.ListBuffer

trait Accesser[A]{
  def set( s: A): Unit
  def get():ListBuffer[A]
}
abstract  class Decision[A]( lst: ListBuffer[A]) extends Accesser[A]

@BeanInfo
case class HogeDecisionBean(id:Int, id2:Int, lst: ListBuffer[Int]) extends Decision[Int](ListBuffer.empty[Int]){
  def set(set: Int) = lst += set
  def get() = lst
}

@BeanInfo
case class FugaDecisionBean(id:Int, lst: ListBuffer[String]) extends Decision[String](ListBuffer.empty[String]){
  def set(s: String) = lst += s
  def get() = lst
}

実際のアプリとDroolsとのExcelデータ連携をする場所
これまではビジネスルールをアプリ内に記載していたが、Droolsを使うことにより
Excelにてビジネスルールを分別することができるようになった。

HogeDecision.scala
package jp.co.drools.droolsscalaexample

import us.bleibinha.droolsscalaexample.Kie

object HogeDecision extends AutoCloseable {

  val session = Kie.newSession_s("DecisionKS")

  def determine[A](facts: Decision[A]): Decision[A] = {
    session.insert(facts)
    session.fireAllRules()
    facts
  }

  override def close(): Unit = {
    if (session !=null )session.dispose()
  }
}

ローンパターン適用。DroolsがExcelとのデータ連携でセッションを確立するが、
セッションクローズは、ローンパターンで透過的に閉じるようにした。

Loan.scala
package jp.co.drools.droolsscalaexample

/**
  * Created by http://d.hatena.ne.jp/gakuzo/20110630/1309442452
  */
class Loan[T <: {def close()}] private (value: T) {

  def foreach[U](f: T => U): U = try {
    f(value)
  } finally {
    value.close()
  }
}

object Loan {
  def apply[T <: {def close()}](value: T) = new Loan(value)
}

参考サイト
ローンパターン