解释器模式

GitHub代码链接
解释器模式(Interpreter Pattern)提供了评估语言和语法表达式的方式。

什么是解释器模式

解释器模式实现了一个表达式的接口,该接口解释一个特定的上下文。这种模式被用在SQL语句处理,符号解释引擎等。

解决的问题

给定一个语言,定义他的文法,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。如果一种特定类型的问题发生的频率足够高,那么就值得将该问题的各个实例表述为一个简单语言中的句子,这样就可以构建一个解释器,解释器通过解析这些句子来解决该问题。

优点

  • 可拓展性高,灵活
  • 易于实现简单的文法

缺点

  • 可使用场景少
  • 对于复杂的文法较难维护
  • 解释器模式会引起类膨胀
  • 解释器模式采用递归调用的方法

代码实现

1. 创建语句的接口

//Expression 语句接口
type Expression interface {
    Interpret(context string) bool
}

2. 创建终端语句类

//TerminalExpression 终端语句类
type TerminalExpression struct {
    Data string
}

//NewTerminalExpression 实例化终端语句类
func NewTerminalExpression(data string) *TerminalExpression {
    return &TerminalExpression{
        Data: data,
    }
}

//Interpret 终端语句类的解释器
func (te *TerminalExpression) Interpret(context string) bool {
    if strings.Contains(context, te.Data) {
        return true
    }
    return false
}

3. 创建逻辑语句类

//OrExpression 或语句类
type OrExpression struct {
    Expr1 Expression
    Expr2 Expression
}

//NewOrExpression 实例化或语句
func NewOrExpression(expr1, expr2 Expression) *OrExpression {
    return &OrExpression{
        Expr1: expr1,
        Expr2: expr2,
    }
}

//Interpret 解释器
func (oe *OrExpression) Interpret(context string) bool {
    return oe.Expr1.Interpret(context) || oe.Expr2.Interpret(context)
}

//AndExpression 与语句类
type AndExpression struct {
    Expr1 Expression
    Expr2 Expression
}

//NewAndExpression 实例化与语句
func NewAndExpression(expr1, expr2 Expression) *AndExpression {
    return &AndExpression{
        Expr1: expr1,
        Expr2: expr2,
    }
}

//Interpret 解释器
func (ae *AndExpression) Interpret(context string) bool {
    return ae.Expr1.Interpret(context) && ae.Expr2.Interpret(context)
}

4. 测试

func OrExpressionTest(t *testing.T) {
    //规则,lee 和 wang 是男性
    lee := NewTerminalExpression("Lee")
    wang := NewTerminalExpression("Wang")
    isMale := NewOrExpression(lee, wang)

    fmt.Println("lee is male? ", isMale.Interpret("Lee"))
}

func AndExpressionTest(t *testing.T) {
    //规则,yang是已婚女性
    yang := NewTerminalExpression("Yang")
    married := NewTerminalExpression("Married")
    isMarried := NewAndExpression(yang, married)

    fmt.Println("Yang is a married women? ", isMarried.Interpret("Married Yang"))
}

上一篇 下一篇