我有以下起点构建一个非常简单的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语言工具以及我想要做的更改?任何指针或建议都会有所帮助。