go: Interpreter Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: Interpreter Pattern 解释器模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/28 21:00
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : context.go
*/
package context
 
type JewelryContext map[string]float64
 
// NewJewelryContext 创建珠宝计价上下文
func NewJewelryContext() JewelryContext {
    return make(JewelryContext)
}
 
// Set 设置变量
func (c JewelryContext) Set(key string, value float64) {
    c[key] = value
}
 
// Get 获取变量
func (c JewelryContext) Get(key string) float64 {
    return c[key]
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Interpreter Pattern 解释器模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/28 21:01
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : expression.go
*/
package expression
 
import (
    "godesginpattern/interpreter/context"
)
 
// Expression 顶层表达式接口
// 所有解释器必须实现此接口
type Expression interface {
    Interpret(ctx context.JewelryContext) float64
}
 
// ------------------------------
// 终结符表达式(最小单元)
// ------------------------------
 
// Number 数字常量
type Number struct {
    value float64
}
 
func NewNumber(value float64) *Number {
    return &Number{value: value}
}
 
func (n *Number) Interpret(ctx context.JewelryContext) float64 {
    return n.value
}
 
// Variable 变量(金价、重量、克拉等)
type Variable struct {
    name string
}
 
func NewVariable(name string) *Variable {
    return &Variable{name: name}
}
 
func (v *Variable) Interpret(ctx context.JewelryContext) float64 {
    return ctx.Get(v.name)
}
 
// ------------------------------
// 非终结符表达式(运算)
// ------------------------------
 
// Add 加法
type Add struct {
    left  Expression
    right Expression
}
 
func NewAdd(left, right Expression) *Add {
    return &Add{left: left, right: right}
}
 
func (a *Add) Interpret(ctx context.JewelryContext) float64 {
    return a.left.Interpret(ctx) + a.right.Interpret(ctx)
}
 
// Sub 减法
type Sub struct {
    left  Expression
    right Expression
}
 
func NewSub(left, right Expression) *Sub {
    return &Sub{left: left, right: right}
}
 
func (s *Sub) Interpret(ctx context.JewelryContext) float64 {
    return s.left.Interpret(ctx) - s.right.Interpret(ctx)
}
 
// Mul 乘法
type Mul struct {
    left  Expression
    right Expression
}
 
func NewMul(left, right Expression) *Mul {
    return &Mul{left: left, right: right}
}
 
func (m *Mul) Interpret(ctx context.JewelryContext) float64 {
    return m.left.Interpret(ctx) * m.right.Interpret(ctx)
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Interpreter Pattern 解释器模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/28 21:01
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : parser.go
*/
package parser
 
import (
    "godesginpattern/interpreter/context"
    "godesginpattern/interpreter/expression"
    "strconv"
    "strings"
)
 
type Parser struct {
    root expression.Expression
}
 
func NewParser(rule string) *Parser {
    stack := []expression.Expression{}
    tokens := strings.Fields(rule)
 
    for _, tok := range tokens {
        switch tok {
        case "+":
            // 正确创建:弹出两个表达式,构造Add
            right := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            left := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            stack = append(stack, expression.NewAdd(left, right))
 
        case "-":
            right := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            left := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            stack = append(stack, expression.NewSub(left, right))
 
        case "*":
            right := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            left := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            stack = append(stack, expression.NewMul(left, right))
 
        default:
            // 数字或变量
            if num, err := strconv.ParseFloat(tok, 64); err == nil {
                stack = append(stack, expression.NewNumber(num))
            } else {
                stack = append(stack, expression.NewVariable(tok))
            }
        }
    }
 
    return &Parser{root: stack[0]}
}
 
func (p *Parser) Calculate(ctx context.JewelryContext) float64 {
    return p.root.Interpret(ctx)
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Interpreter Pattern 解释器模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/28 21:01
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : price_service.go
*/
package service
 
import (
    "godesginpattern/interpreter/context"
    "godesginpattern/interpreter/parser"
    "log"
)
 
type JewelryPriceService struct{}
 
func NewJewelryPriceService() *JewelryPriceService {
    return &JewelryPriceService{}
}
 
// 黄金价格 = 金价 × 重量 + 工费
func (j *JewelryPriceService) CalculateGoldPrice() {
    rule := "goldPrice weight * craftFee +"
    ctx := context.NewJewelryContext()
    ctx.Set("goldPrice", 600)
    ctx.Set("weight", 30)
    ctx.Set("craftFee", 500)
 
    price := parser.NewParser(rule).Calculate(ctx)
    log.Printf("黄金手镯:%.2f 元", price)
}
 
// 钻石价格 = 克拉价 × 克拉 + 金托价
func (j *JewelryPriceService) CalculateDiamondPrice() {
    rule := "diamondPrice carat * metalPrice +"
    ctx := context.NewJewelryContext()
    ctx.Set("diamondPrice", 50000)
    ctx.Set("carat", 0.8)
    ctx.Set("metalPrice", 2000)
 
    price := parser.NewParser(rule).Calculate(ctx)
    log.Printf("钻石戒指:%.2f 元", price)
}
 
// 会员折扣价 = (金价 × 重量 + 工费) × 折扣
func (j *JewelryPriceService) CalculateVIPPrice() {
    rule := "goldPrice weight * craftFee + vipDiscount *"
    ctx := context.NewJewelryContext()
    ctx.Set("goldPrice", 600)
    ctx.Set("weight", 30)
    ctx.Set("craftFee", 500)
    ctx.Set("vipDiscount", 0.9)
 
    price := parser.NewParser(rule).Calculate(ctx)
    log.Printf("会员折后价:%.2f 元", price)
}

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Interpreter Pattern 解释器模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/28 21:08
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : interpreter bll.go
 
Interpreter /
├── cmd/
│   └── main.go
├── internal/  # 内部业务包(外部不可引用)
│   ├── context/   # 上下文环境(变量容器)
│   │   └── context.go
│   ├── expression/ # 解释器表达式核心(终结符+非终结符)
│   │   └── expr.go
│   ├── parser/ # 语法解析器
│   │   └── parser.go
│   └── service/   # 业务服务层
│       └── price_service.go
└── go.mod
 
*/
 
package bll
 
import (
    "godesginpattern/interpreter/service"
    "log"
)
 
func InterpreterMain() {
    log.Println("=== 珠宝计价系统(企业级解释器模式)===")
 
    srv := service.NewJewelryPriceService()
    srv.CalculateGoldPrice()
    srv.CalculateDiamondPrice()
    srv.CalculateVIPPrice()
}

输出:

相关推荐
YikNjy13 分钟前
break和continue
java·开发语言·算法
秋930 分钟前
java项目中cpu飙升排查及解决方法
java·开发语言
野生技术架构师31 分钟前
牛客网2026最新大厂Java高频面试题精选(附标准答案)
java·开发语言
PH = 735 分钟前
JAVA的SPI机制
java·开发语言
IT猿手1 小时前
多目标优化算法:多目标蛇优化算法(Multiple Objective Snake Optimizer,MOSO)(提供MATLAB代码)
开发语言·算法·matlab·动态路径规划·光伏模型参数估计
朔北之忘 Clancy1 小时前
2026 年 3 月青少年软编等考 C/C++ 一级真题解析
c语言·开发语言·c++·青少年编程·题解·考级
小成202303202651 小时前
C++~01面向对象基础
开发语言·c++
会编程的土豆1 小时前
Go 方法接收者超清晰笔记(类型名 vs 变量名)
开发语言·笔记·golang
workflower1 小时前
具身智能研究对象:物理交互中的智能行为
设计模式·动态规划·软件工程·软件构建·scrum
YY&DS2 小时前
Qt 嵌入 CEF 在 Linux 下必须设置 `QT_XCB_GL_INTEGRATION=xcb_egl才能加载网页
linux·开发语言·qt