Skip to main content
 首页 » 编程设计

使用go实现解释器模式

2022年07月19日155mfrbuaa

解释器模式

定义

解释器模式(interpreter):给定一种语言,定义它的文法的一种表示,并定一个解释器,这个解释器使用该表示来解释语言中的句子。

解释器模式的意义在于,它分离多种复杂功能的实现,每个功能只需关注自身的解释。

对于调用者不用关心内部的解释器的工作,只需要用简单的方式组合命令就可以。

优点

1、可扩展性比较好,灵活;

2、增加了新的解释表达式的方式;

3、易于实现简单文法。

缺点

1、可利用场景比较少;

2、对于复杂的文法比较难维护;

3、解释器模式会引起类膨胀。

适用范围

解释器模式的代码实现比较灵活,没有固定的模板。我们前面也说过,应用设计模式主要是应对代码的复杂性,实际上,解释器模式也不例外。它的代码实现的核心思想,就是将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。一般的做法是,将语法规则拆分成一些小的独立的单元,然后对每个单元进行解析,最终合并为对整个语法规则的解析。

代码实现

这里简单实现了一个加减的运算器,我们对每种运算定义对应的方法,避免所有的运算操作放到一个函数中,这就体现了解释器模式的核心思想,将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。

type Expression interface { 
	Interpret() int 
} 
 
type NumberExpression struct { 
	val int 
} 
 
func (n *NumberExpression) Interpret() int { 
	return n.val 
} 
 
type AdditionExpression struct { 
	left, right Expression 
} 
 
func (n *AdditionExpression) Interpret() int { 
	return n.left.Interpret() + n.right.Interpret() 
} 
 
type SubtractionExpression struct { 
	left, right Expression 
} 
 
func (n *SubtractionExpression) Interpret() int { 
	return n.left.Interpret() - n.right.Interpret() 
} 
 
type Parser struct { 
	exp   []string 
	index int 
	prev  Expression 
} 
 
func (p *Parser) Parse(exp string) { 
	p.exp = strings.Split(exp, " ") 
 
	for { 
		if p.index >= len(p.exp) { 
			return 
		} 
		switch p.exp[p.index] { 
		case "+": 
			p.prev = p.newAdditionExpression() 
		case "-": 
			p.prev = p.newSubtractionExpression() 
		default: 
			p.prev = p.newNumberExpression() 
		} 
	} 
} 
 
func (p *Parser) newAdditionExpression() Expression { 
	p.index++ 
	return &AdditionExpression{ 
		left:  p.prev, 
		right: p.newNumberExpression(), 
	} 
} 
 
func (p *Parser) newSubtractionExpression() Expression { 
	p.index++ 
	return &SubtractionExpression{ 
		left:  p.prev, 
		right: p.newNumberExpression(), 
	} 
} 
 
func (p *Parser) newNumberExpression() Expression { 
	v, _ := strconv.Atoi(p.exp[p.index]) 
	p.index++ 
	return &NumberExpression{ 
		val: v, 
	} 
} 
 
func (p *Parser) Result() Expression { 
	return p.prev 
} 

测试代码

func TestInterpreter(t *testing.T) { 
	p := &Parser{} 
	p.Parse("1 + 3 + 3 + 3 + 3") 
	res := p.Result().Interpret() 
	expect := 13 
	if res != expect { 
		t.Fatalf("expect %d got %d", expect, res) 
	} 
	t.Log(res) 
} 

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/解释器模式
【大话设计模式】https://book.douban.com/subject/2334288/
【极客时间】https://time.geekbang.org/column/intro/100039001
【设计模式】https://github.com/senghoo/golang-design-pattern
【解释器模式】https://boilingfrog.github.io/2021/11/30/使用go实现解释器模式/


本文参考链接:https://www.cnblogs.com/ricklz/p/15624074.html
阅读延展