解释器模式

定义

解释器模式(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实现解释器模式/

设计模式学习-使用go实现解释器模式的更多相关文章

  1. C#设计模式学习笔记:(23)解释器模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...

  2. 设计模式之第5章-解释器模式(Java实现)

    设计模式之第5章-解释器模式(Java实现) “开个商店好麻烦,做个收单的系统,发现类的方法好多.”“真是的,不就是简单的四则运算,这都不会!”你说你会啊.来来来,你把以下的方法用代码写出来: a+b ...

  3. 我所理解的设计模式(C++实现)——解释器模式(Interpreter Pattern)

    概述: 未来机器智能化已然成为趋势,现在手机都能听懂英语和普通话,那我大中华几万种方言的被智能化也许也是趋势,我们的方言虽然和普通话相似,但是还是不一样的.这可能需要一个新的语法分析器来帮助我们. 我 ...

  4. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

  5. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  6. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  7. [Python设计模式] 第27章 正则表达式——解释器模式

    github地址:https://github.com/cheesezh/python_design_patterns 解释器模式 解释器模式,给定一个语言,定一个它的文法的一种表示,并定一个一个解释 ...

  8. 【设计模式】行为型11解释器模式(Interpreter Pattern)

      解释器模式(Interpreter Pattern) 解释器模式应用场景比较小,也没有固定的DEMO,中心思想就是自定义解释器用来解释固定的对象. 定义:给定一个语言,定义它的文法表示,并定义一个 ...

  9. 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)

    1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e,  要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...

  10. javascript设计模式学习之十三——职责链模式

    一.职责链的定义和使用场景 职责链模式的定义是,职责链模式将一系列可能会处理请求的对象连接成一条链,请求在这些对象之间一次传递,直到遇到一个可以处理它的对象.从而避免请求的发送者和接收者之间的耦合关系 ...

随机推荐

  1. mit6.s081 lab2: system calls

    1.system call tracing(moderate) 要求:创建一个系统调用来实现跟踪特性,它采用一个参数来指定跟踪哪一个系统调用,例如:跟踪fork系统调用,程序调用trace(1< ...

  2. C++20 | std::span 陣列、容器的代理人

    在 C++ 裡頭有相當多「容器」.從原生的陣列,到標準庫 STL 的 vector, array, list, queue, map, set, -.有時候我們只是想以檢視的角度去看一個容器,或是其中 ...

  3. 传统与现代可视化 PK:再生水厂二维工艺组态系统

    前言 随着可视化技术的进步与发展,传统再生水厂组态系统所展示的组态页面已逐渐无法满足当前现阶段多样化的展示手段.使得系统对污泥处理处置及生产运行成本方面的监控.分析方面较为薄弱,急需对信息化应用成果和 ...

  4. iview upload 上传文件样例

    iview upload 组件官网上给出的用法是,选择附件后就立马上传附件.我不想让他立马上传,我想让他和其他一些信息一起上传,百度查了一些资料照大神总结的例子实现了现在分享一下. <Uploa ...

  5. 【驱动】SPI驱动分析(二)-SPI驱动框架

    SPI驱动框架 SPI驱动属于总线-设备-驱动模型的,与I2C总线设备驱动模型相比,大体框架是一样,他们都是实际的总线.总体框架如下图所示: 从上到下,分为三层,用户空间,内核空间,和硬件层. 用户空 ...

  6. 《3D编程模式》写书-第2次记录

    大家好,目前我已经完成了"拼接模式"."撤销重做模式"."ECS模式"的初稿 下面会给出它们的使用场景,如果您正好能用到,请联系我提前阅读模 ...

  7. WebGPU光追引擎基础课系列目录

    大家好~我开设了"WebGPU光追引擎基础课"的线上课程,从0开始,在课上带领大家现场写代码,使用WebGPU开发基础的光线追踪引擎 课程重点在于基于GPU并行计算,实现BVH构建 ...

  8. vue2+高德地图web端开发

    https://blog.csdn.net/qq_51553982/article/details/123014412

  9. Go socket 编程源码解析(上)

    0. socket 介绍 Liunx 中一切皆文件.通过文件描述符和系统调用号可以实现对任何设备的访问.同样的,socket 也是一种文件描述符.通过 socket 可以建立网络传输.对于 TCP 和 ...

  10. idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql

    本文为博主原创,未经允许不得转载: mybatis plus 使用过程中已经很大程度提升了我们开发的效率,因为它内部已经对单表的操作进行了完美的封装,但是关联表操作时, 这时就需要自己定义sql,自定 ...