设计模式学习-使用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设计模式学习之十三——职责链模式
一.职责链的定义和使用场景 职责链模式的定义是,职责链模式将一系列可能会处理请求的对象连接成一条链,请求在这些对象之间一次传递,直到遇到一个可以处理它的对象.从而避免请求的发送者和接收者之间的耦合关系 ...
随机推荐
- 围绕ChatGPT,做了点小事,赚了点小钱
大家好,我是章北海mlpy 作为 ChatGPT 日活用户,分享一下经验和用它做的一些小事吧. 经验不敢当,只是觉得大家把ChatGPT当成了高大上的黑科技,其实它就是个工具,就像你买了个新手机一样, ...
- 一个简单的例子看明白 async await Task
测试代码: 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using Sys ...
- Mac | HomeBrew 安装 & 配置 MySQL
这个是我最新并且一直推崇的方法: 1.安装:brew install mysql 2.开启mysql:mysql.server start 3.使用mysql的配置脚本:/usr/local/opt/ ...
- 详解KubeEdge EdgeMesh v1.15 边缘CNI特性
本文分享自华为云社区<KubeEdge EdgeMesh v1.15 边缘CNI特性原理及功能详解>,作者:达益鑫 |南开大学,刘家伟.吴锟 |DaoCloud,王杰章 |华为云 特性研发 ...
- vue学习笔记 十二、通过计算属性获取定义的状态数据
系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...
- C#设计模式10——外观模式的写法
什么是外观模式? 外观模式(Facade Pattern)又称门面模式,是一种结构型设计模式,它提供了一个统一的接口,用来访问一个子系统中一群功能相关联的接口.外观模式定义了一个高层接口,让子系统更容 ...
- Kubernetes APIServer 最佳实践
1. kubernetes 整体架构 kubernetes 由 master 节点和工作节点组成.其中,master 节点的组件有 APIServer,scheduler 和 controller-m ...
- idea导入maven项目结构不全
本文为博主原创,转载请注明出处 将本地的项目导入idea中,其操作第一步为: File->open->选中导入maven项目的pom文件,正常情况通过该步骤项目就会导入到idea中. 通过 ...
- Vue事件方法中this.属性名
vue事件方法中访问data对象中的成员 : this.属性名 注意: 如果事件处理代码没有写到methods中,而是写在行内则不需要this.
- 今天是个好日子,TaxCore(POS软件)备案指北
POS软件是什么?你好意思吗,还在用老掉牙的Winform. 关于POS 销售终端--POS(point of sale)是一种多功能终端,把它安装在信用卡的特约商户和受理网点中与计算机联成网络,就能 ...