GO设计模式——17、解释器模式(行为型)

目录

[解释器模式(Interpreter Pattern)](#解释器模式(Interpreter Pattern))

解释器模式的核心角色:

优缺点

代码实现


解释器模式(Interpreter Pattern)

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

解释器模式核心角色

  • 抽象表达式(Abstract Expression):定义了抽象的解释器接口,用来解释语言中的元素,可以是终止符,也可以是非终止符。
  • 终止符表达式(Terminal Expression):实现了抽象表达式中的解释器接口,用来存储语言中的终止符,它们不需要再次解释,通常会返回具体的结果。
  • 非终止符表达式(Nonterminal Expression):也实现了抽象表达式中的解释器接口,用来存储语言中的非终止符。
  • 上下文(Context):存储解释器解释的信息,并调用解释器进行解释。

优缺点

(1)优点:

  • 可扩展性比较好,灵活。
  • 增加了新的解释表达式的方式。
  • 易于实现简单文法。

(2)缺点:

  • 可利用场景比较少。
  • 对于复杂的文法比较难维护。
  • 解释器模式会引起类膨胀。
  • 解释器模式采用递归调用方法。

代码实现

Go 复制代码
package main

import (
    "fmt"
    "strconv"
    "strings"
)

// 解释器接口
type Node interface {
    Interpret() int //解释方法
}

// 数据节点
type ValNode struct {
    val int
}

func (vn *ValNode) Interpret() int {
    return vn.val
}

// =============加法节点=============
type AddNode struct {
    left, right Node
}

func (an *AddNode) Interpret() int {
    return an.left.Interpret() + an.right.Interpret()
}

// =============减法节点=============
type SubNode struct {
    left, right Node
}

func (an *SubNode) Interpret() int {
    return an.left.Interpret() - an.right.Interpret()
}

// =============解释对象=============
type Parser struct {
    exp   []string //表达式
    index int      //索引
    prev  Node     //前序节点
}

func (p *Parser) newValNode() Node { //执行数据操作
    v, _ := strconv.Atoi(p.exp[p.index])
    p.index++
    return &ValNode{val: v}
}
func (p *Parser) newAddNode() Node { //执行加法操作( + )
    p.index++
    return &AddNode{
       left:  p.prev,
       right: p.newValNode(),
    }
}
func (p *Parser) newSubNode() Node { //执行减法操作( - )
    p.index++
    return &SubNode{
       left:  p.prev,
       right: p.newValNode(),
    }
}
func (p *Parser) Result() Node { //返回结果
    return p.prev
}
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.newAddNode()
       case "-":
          p.prev = p.newSubNode()
       default:
          p.prev = p.newValNode()

       }
    }
}
func main() {
    p := Parser{}
    p.Parse("1 + 2 + 3 - 4 + 10") //是通过空格进行解释的
    fmt.Println(p.Result().Interpret())
}
相关推荐
明月_清风9 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
江湖十年10 小时前
在 Go 中使用 dyno 包处理动态对象
后端·面试·go
a1879272183110 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
纪卓志George11 小时前
打破语言范式:在 Go 里用动态代理实现 AOP
架构·go
平头哥AI12 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
2601_9622965113 小时前
如何使用Golang包路径_管理本地和远程模块引用
golang·数据转换·变量定义·常用库·编程语言区别
FfHUCisI17 小时前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
Carl_奕然17 小时前
【智能体】Agent的四种设计模式之:React(2026最新版)
javascript·人工智能·python·react.js·设计模式·语言模型
cfm_291417 小时前
Spring核心设计模式
java·spring·设计模式
我不会起名字32218 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·