设计模式-解释器模式
解释器(Interpreter)模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。(学习)
解释器模式的结构
下面就以一个示意性的系统为例,讨论解释器模式的结构。系统的结构图如下:
模式所涉及的角色如下所示:
- 抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。
- 终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
- 非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其它关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
- 环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。
为了说明解释器模式的实现办法,这里给出一个最简单的文法和对应的解释器模式的实现,这就是模拟java语言中对bool表达式进行操作和求值。
在这个语言中终结符是bool变量,也就是常量true和false。非终结符表达式包含运算符and, or和not等布尔表达式。这个简单的文法如下:
Expression ::= Constant | Variable | Or | And | Not
And ::= Expression 'AND' Expression
Or ::= Expression 'OR' Expression
Not ::= 'NOT' Expression
Variable ::= 任何标识符
Constant ::= 'true' | 'false'
解释器模式的结构图如下:
源代码
package Interpreter /** * 抽像表达式角色 * */ abstract class Expression { /** * 以环境为准,本方法解释给定的任何一个表达式 * */ abstract fun interpret(context: Context): Boolean /** * 检验两个表达式在结构上是否相同 * */ abstract fun equal(other: Any?): Boolean /** * 返回表达式的hash code * */ abstract fun hash_code(): Int /** * 将表达式转换成字符串 * */ abstract fun to_string(): String }
package Interpreter /** * 一个Constant对象代表一个布尔常量 * */ class Constant constructor(value: Boolean) : Expression() { var value = false init { this.value = value } override fun interpret(context: Context): Boolean { return value } override fun equal(other: Any?): Boolean { if (other != null && other is Constant) { return this.value == other.value } return false } override fun hash_code(): Int { return to_string().hashCode() } override fun to_string(): String { return value.toString() } }
package Interpreter /** * 一个Variable对象代表一个有名变量 * */ class Variable constructor(name: String) : Expression() { var name = "" init { this.name = name } override fun interpret(context: Context): Boolean { return context.lookup(this) } override fun equal(other: Any?): Boolean { if (other != null && other is Variable) { return this.name == other.name } return false } override fun hash_code(): Int { return to_string().hashCode() } override fun to_string(): String { return name } }
package Interpreter /** * 代表逻辑"与"操作的And类,表示由两个bool表达式通过逻辑"与"操作给出一个新的bool表达式的操作 * */ class And constructor(left: Expression, right: Expression) : Expression() { private var left: Expression? = null private var right: Expression? = null init { this.left = left this.right = right } override fun interpret(context: Context): Boolean { return left!!.interpret(context) && right!!.interpret(context) } override fun equal(other: Any?): Boolean { if (other != null && other is And) { return left!!.equal(other.left) && right!!.equal(other.right) } return false } override fun hash_code(): Int { return to_string().hashCode() } override fun to_string(): String { return "(${left!!.to_string()} AND ${right!!.to_string()})" } }
package Interpreter /** * 代表逻辑"或"操作的Or类,代表由两个bool表达式通过逻辑"或"操作给出一个新的bool表达式的操作 * */ class Or constructor(left: Expression, right: Expression) : Expression() { private var left: Expression? = null private var right: Expression? = null init { this.left = left this.right = right } override fun interpret(context: Context): Boolean { return left!!.interpret(context) || right!!.interpret(context) } override fun equal(other: Any?): Boolean { if (other != null && other is Or) { return left!!.equal(other.left) && right!!.equal(other.right) } return false } override fun hash_code(): Int { return to_string().hashCode() } override fun to_string(): String { return "(${left!!.to_string()} OR ${right!!.to_string()})" } }
package Interpreter /** * 代表逻辑"非"操作的Not类,代表一个由bool值表达式通过逻辑"非"操作给出一个新的bool表达式的操作 * */ class Not constructor(expression: Expression) : Expression() { private var exp: Expression? = null init { this.exp = expression } override fun interpret(context: Context): Boolean { return !exp!!.interpret(context) } override fun equal(other: Any?): Boolean { if (other != null && other is Not) { return exp!!.equal(other.exp) } return false } override fun hash_code(): Int { return to_string().hashCode() } override fun to_string(): String { return "(Not ${exp!!.to_string()})" } }
package Interpreter /** * 环境类,定义出从变量到布尔值的一个影射 * */ class Context { private val map = HashMap<Variable, Boolean>() fun assign(variable: Variable, value: Boolean) { map.put(variable, value) } @Throws(IllegalArgumentException::class) fun lookup(variable: Variable): Boolean { return map[variable] ?: throw IllegalArgumentException() } }
代码测试
val context = Context() val x = Variable("x") val y = Variable("y") val true_ = Constant(true) context.assign(x, false) context.assign(y, true) val expression = Or(And(true_,x), And(y,Not(x))) println("x:${x.interpret(context)}") println("y:${y.interpret(context)}") println("${expression.to_string()} = ${expression.interpret(context)}")
结果
x:false y:true ((true AND x) OR (y AND (Not x))) = true