解释器模式
定义
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
优点
- 扩展性强,若要新增乘,除,添加相应的非终结表达式,修改计算逻辑即可。
缺点
- 需要建大量的类,因为每一种语法都要建一个非终结符的类。
- 解释的时候采用递归调用方法,导致有时候函数的深度会很深,影响效率。
场景
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
代码
package Interpreter import "strings" type Expression interface { Interpret(variables map[string]Expression) int } type Integer struct { integer int } func (n *Integer) Interpret(variables map[string]Expression) int { return n.integer } type Plus struct { leftOperand Expression rightOperand Expression } func (p *Plus) Interpret(variables map[string]Expression) int { return p.leftOperand.Interpret(variables) + p.rightOperand.Interpret(variables) } func (e *Evaluator) Interpret(context map[string]Expression) int { return e.syntaxTree.Interpret(context) } type Variable struct { name string } type Node struct { value interface{} next *Node } type Stack struct { top *Node size int } func (s *Stack) Push(value interface{}) { s.top = &Node{ value: value, next: s.top, } s.size++ } func (s *Stack) Pop() interface{} { if s.size == 0 { return nil } value := s.top.value s.top = s.top.next s.size-- return value } func (v *Variable) Interpret(variables map[string]Expression) int { value, found := variables[v.name] if !found { return 0 } return value.Interpret(variables) } type Evaluator struct { syntaxTree Expression } func NewEvaluator(expression string) *Evaluator { expressionStack := new(Stack) for _, token := range strings.Split(expression, " ") { switch token { case "+": right := expressionStack.Pop().(Expression) left := expressionStack.Pop().(Expression) subExpression := &Plus{left, right} expressionStack.Push(subExpression) default: expressionStack.Push(&Variable{token}) } } syntaxTree := expressionStack.Pop().(Expression) return &Evaluator{syntaxTree: syntaxTree} }
package Interpreter import "testing" import "github.com/stretchr/testify/assert" func TestInterpret(t *testing.T) { expression := "w x z +" sentence := NewEvaluator(expression) variable := make(map[string]Expression) variable["w"] = &Integer{6} variable["x"] = &Integer{10} variable["z"] = &Integer{41} result := sentence.Interpret(variable) assert.Equal(t, 51, result) }
其他设计模式
设计模式Git源代码
00简单工厂模式
01工厂方法模式
02抽象工厂模式
03外观模式
04建造者模式
05桥接模式
06命令模式
07迭代器模式
08模板模式
09访问者模式
10备忘录模式
11责任链模式
12中介模式
13原型模式
14状态模式
15策略模式
16享元模式
17组合模式
18解释器模式
19单例模式
20适配器模式
21代理模式
22装饰器模式
23观察者模式