如何为描述简单的布尔规则构建Scala DSL?

时间:2015-10-23 15:19:59

标签: scala dsl

我有以下起点构建一个非常简单的DSL来构建布尔规则。下面:

abstract class Rule {
  def evaluate(): Boolean

  def messages(): String

  def condition(name: String)(x: => Boolean): Rule = {
    Condition(name, () => x)
  }

  def not(): Rule = {
    NotRule(this)
  }

  def or(name: String)(x: => Boolean): Rule = {
    val r1 = this
    val r2 = condition(name)(x)
    OrRule(r1, r2)
  }

  def and(name: String)(x: => Boolean): Rule = {
    val r1 = this
    val r2 = condition(name)(x)
    AndRule(r1, r2)
  }
}

object Rule {
  def apply(name: String)(x: => Boolean): Rule = {
    Condition(name, () => x)
  }
}

case class Condition(message: String, f: () => Boolean) extends Rule {
  def messages(): String = s"( $message )"

  override def evaluate = f()
}

case class AndRule(r1: Rule, r2: Rule) extends Rule {
  def messages(): String = s"(${r1.messages()} AND ${r2.messages()})"

  override def evaluate = r1.evaluate() && r2.evaluate()
}

case class OrRule(r1: Rule, r2: Rule) extends Rule {
  def messages(): String = s"(${r1.messages()} OR ${r2.messages()})"

  override def evaluate = r1.evaluate() || r2.evaluate()
}

case class NotRule(r: Rule) extends Rule {
  def messages(): String = s"( NOT ${r.messages()} )"

  override def evaluate = !r.evaluate()
}

示例:

object RulesTest {

  def main(args: Array[String]) {
    var a = 1
    val b = 2

    val r =
      Rule("a must be 1")(a == 1).and("b must be 2")(b == 2)

    println(r.evaluate())
    println(r.messages())
    a = 2
    println(r.evaluate())
    println(r.messages())
  }
}

我想指定一个这样的规则:

val r1 = Rule("a must be 1")(a == 1) AND ("b must be 2")(b == 2) OR NOT ("a divisible by b")(a % b != 0)

val r2 = Rule("c must be 4")(c == 4) AND ("d must be 5")(d == 5) AND ("d divisible by c")(d % c != 0)

val r3 = r1 AND NOT r2

这样做,我应该得到评估(真/假)和消息,如:

( a must be 1 ) AND ( b must be 2 ) OR ( NOT ( a divisible by b) ) AND NOT ( ( c must be 4 ) AND ( d must be b ) AND ( d divisible by c ) )

此消息将解释规则失败的原因。

可以使用哪些Scala语言工具以及我想要做的更改?任何指针或建议都会有所帮助。

0 个答案:

没有答案