设计模式学习-使用go实现解释器模式
解释器模式
定义
解释器模式(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实现解释器模式的更多相关文章
- C#设计模式学习笔记:(23)解释器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...
- 设计模式之第5章-解释器模式(Java实现)
设计模式之第5章-解释器模式(Java实现) “开个商店好麻烦,做个收单的系统,发现类的方法好多.”“真是的,不就是简单的四则运算,这都不会!”你说你会啊.来来来,你把以下的方法用代码写出来: a+b ...
- 我所理解的设计模式(C++实现)——解释器模式(Interpreter Pattern)
概述: 未来机器智能化已然成为趋势,现在手机都能听懂英语和普通话,那我大中华几万种方言的被智能化也许也是趋势,我们的方言虽然和普通话相似,但是还是不一样的.这可能需要一个新的语法分析器来帮助我们. 我 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- [Python设计模式] 第27章 正则表达式——解释器模式
github地址:https://github.com/cheesezh/python_design_patterns 解释器模式 解释器模式,给定一个语言,定一个它的文法的一种表示,并定一个一个解释 ...
- 【设计模式】行为型11解释器模式(Interpreter Pattern)
解释器模式(Interpreter Pattern) 解释器模式应用场景比较小,也没有固定的DEMO,中心思想就是自定义解释器用来解释固定的对象. 定义:给定一个语言,定义它的文法表示,并定义一个 ...
- 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)
1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...
- javascript设计模式学习之十三——职责链模式
一.职责链的定义和使用场景 职责链模式的定义是,职责链模式将一系列可能会处理请求的对象连接成一条链,请求在这些对象之间一次传递,直到遇到一个可以处理它的对象.从而避免请求的发送者和接收者之间的耦合关系 ...
随机推荐
- Jenkins + SVN
安装插件 Localization: Chinese (Simplified) Subversion 配置国内源 http://mirror.tuna.tsinghua.edu.cn/jenkins/ ...
- SQL Server 2016 安装
数据库安装 选择全新安装模式继续安装 输入产品秘钥:这里使用演示秘钥进行 接受许可 规则检测 可以后期再开放防火墙对外端口 选择需要安装的功能,想省事可以选择[全选] 可以安装JDK,这边选择取消 P ...
- 如何在 EF Core 中使用乐观并发控制
什么是乐观并发控制? 乐观并发控制是一种处理并发访问的数据的方法,它基于一种乐观的假设,即认为并发访问的数据冲突的概率很低.在乐观并发控制中,系统不会立即对并发访问的数据进行加锁,而是在数据被修改时, ...
- VS Code的C/C++环境配置的傻瓜式教程(看这一篇就够了)
html: toc: true VS Code的C/C++环境配置的傻瓜式教程(看这一篇就够了) 写在前面的话 作者在学习使用vscode写C代码的时候,根据网上很多参差不齐的教程踩了不少的坑,很多教 ...
- Ansible--批量创建lvm
--- - hosts: all tasks: - block: - name: 创建1000M的逻辑卷lv1 lvol: vg: vg0 lv: lv1 size: 1000 - name: 逻辑卷 ...
- Nginx--引用多配置文件
在nginx.conf的http模块,include 指定某个目录下的*.conf user nginx; worker_processes auto; error_log /var/log/ngin ...
- redis管道技术pipeline一 ——api
import java.io.UnsupportedEncodingException; import java.util.Set; import org.springframework.beans. ...
- 最全!即学即会 Serverless Devs 基础入门(上)
作者 | 刘宇(花名:江昱) 在上篇<即学即会 Serverless | 如何解决 Serverless 应用开发部署的难题>中,我们阐述了工具链的重要性,那么本文将带领各位快速实现 Se ...
- Redis 也支持全文搜索 了?这也太强了
在 2021 年我就了解到 RediSearch 这个项目,并已经把它用于我的开源项目 newbee-mall-pro 中. 就我的使用体验来说,简单场景下,用来平替 Elasticsearch 的使 ...
- python之单线程、多线程、多进程
一.基本概念 进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础. 在当代面向线程设计的计算机结构中,进程是线程的容器.程 ...