解释器模式
解释器模式提供了评估语言的愈发或表达式的方式,它属于行为型模式,这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在SQL解析、符号处理引擎等。
介绍:
意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
主要解决:对于一些固定文法构建一个解释句子的解释器。
何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这种就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
如何解决:构建语法树,定义终结符与非终结符。
关键代码:构建环境类,包含解释器之外的一些全局信息,一般是map
应用:编译器、运算表达式计算
优点:
- 可扩展性好,灵活
- 增加了新的解释表达式的方式
- 易于实现简单文法
缺点:
- 可利用常见较少
- 对于复杂的文法比较难维护
- 解释器模式会引起类膨胀
- 解释器模式采用递归调用方式
使用场景:
- 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
- 2、一些重复出现的问题可以用一种简单的语言来进行表达。
- 3、一个简单语法需要解释的场景。
实现
我们将创建一个接口Expression和实现了Expression接口的实体类。定义作为上下文中主要解释器的TerminalExpression 类。其他的类 OrExpression、AndExpression 用于创建组合式表达式。
InterpreterPatternDemo,我们的演示类使用 Expression 类创建规则和演示表达式的解析。
代码:
package InterpreterPattern
type AndExpression struct {
expr1 Expression
expr2 Expression
}
func (a *AndExpression) AndExpression(expr1 Expression, expr2 Expression) {
a.expr1 = expr1
a.expr2 = expr2
}
func (a *AndExpression) Interpret(context string) bool {
return a.expr1.Interpret(context) && a.expr2.Interpret(context);
}
package InterpreterPattern
type Expression interface {
Interpret(context string) bool
}
package InterpreterPattern
type OrExpression struct {
expr1 Expression
expr2 Expression
}
func (o *OrExpression) OrExpression(expr1 Expression, expr2 Expression) {
o.expr1 = expr1
o.expr2 = expr2
}
func (o *OrExpression) Interpret(context string) bool {
return o.expr1.Interpret(context) || o.expr2.Interpret(context);
}
package InterpreterPattern
import "strings"
type TerminalExpression struct {
Data string
}
func (t *TerminalExpression) TerminalExpression(data string) {
t.Data = data
}
func (t *TerminalExpression) Interpret(context string) bool {
if strings.Contains(context, t.Data) {
return true
}
return false
}
测试:
package InterpreterPattern
func GetMaleExpression() Expression {
robert := new(TerminalExpression)
robert.TerminalExpression("Robert")
john := new(TerminalExpression)
john.TerminalExpression("John")
orExpression := new(OrExpression)
orExpression.OrExpression(robert, john)
return orExpression
}
func GetMarriedWomanExpression() Expression {
julie := new(TerminalExpression)
julie.TerminalExpression("Julie")
married := new(TerminalExpression)
married.TerminalExpression("Married")
andExpression := new(AndExpression)
andExpression.AndExpression(julie, married)
return andExpression
}
func testInterpreterPattern() {
isMale := InterpreterPattern.GetMaleExpression()
isMarriedWoman := InterpreterPattern.GetMarriedWomanExpression()
fmt.Println("John is male? ", isMale.Interpret("John"))
fmt.Println("Julie is a married women? ", isMarriedWoman.Interpret("Married Julie"))
}
输出:
John is male? true
Julie is a married women? true