解释器模式

定义

解释器模式(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. 围绕ChatGPT,做了点小事,赚了点小钱

    大家好,我是章北海mlpy 作为 ChatGPT 日活用户,分享一下经验和用它做的一些小事吧. 经验不敢当,只是觉得大家把ChatGPT当成了高大上的黑科技,其实它就是个工具,就像你买了个新手机一样, ...

  2. 一个简单的例子看明白 async await Task

    测试代码: 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using Sys ...

  3. Mac | HomeBrew 安装 & 配置 MySQL

    这个是我最新并且一直推崇的方法: 1.安装:brew install mysql 2.开启mysql:mysql.server start 3.使用mysql的配置脚本:/usr/local/opt/ ...

  4. 详解KubeEdge EdgeMesh v1.15 边缘CNI特性

    本文分享自华为云社区<KubeEdge EdgeMesh v1.15 边缘CNI特性原理及功能详解>,作者:达益鑫 |南开大学,刘家伟.吴锟 |DaoCloud,王杰章 |华为云 特性研发 ...

  5. vue学习笔记 十二、通过计算属性获取定义的状态数据

    系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...

  6. C#设计模式10——外观模式的写法

    什么是外观模式? 外观模式(Facade Pattern)又称门面模式,是一种结构型设计模式,它提供了一个统一的接口,用来访问一个子系统中一群功能相关联的接口.外观模式定义了一个高层接口,让子系统更容 ...

  7. Kubernetes APIServer 最佳实践

    1. kubernetes 整体架构 kubernetes 由 master 节点和工作节点组成.其中,master 节点的组件有 APIServer,scheduler 和 controller-m ...

  8. idea导入maven项目结构不全

    本文为博主原创,转载请注明出处 将本地的项目导入idea中,其操作第一步为: File->open->选中导入maven项目的pom文件,正常情况通过该步骤项目就会导入到idea中. 通过 ...

  9. Vue事件方法中this.属性名

    vue事件方法中访问data对象中的成员 : this.属性名 注意: 如果事件处理代码没有写到methods中,而是写在行内则不需要this.

  10. 今天是个好日子,TaxCore(POS软件)备案指北

    POS软件是什么?你好意思吗,还在用老掉牙的Winform. 关于POS 销售终端--POS(point of sale)是一种多功能终端,把它安装在信用卡的特约商户和受理网点中与计算机联成网络,就能 ...