Golang学习笔记_49——解释器模式

火影  论坛元老 | 2025-3-11 20:30:58 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1010|帖子 1010|积分 3030

Golang学习笔记_46——状态模式
Golang学习笔记_47——访问者模式
Golang学习笔记_48——中介者模式


  

一、核心概念

1. 定义

解释器模式是一种行为型设计模式,通过定义语言的文法结构和解释器,实现对特定语法规则的解析实验。其核心特点包括:
文法抽象:将语法规则转化为类层次结构
递归解析:通过组合模式构建抽象语法树(AST)
动态扩展:支持新增表达式范例而不修改现有代码
2. 解决的问题

语法解析:将复杂语法规则转化为可实验结构
表达式求值:实现数学公式、逻辑表达式等动态盘算
范畴语言:为特定范畴创建专用解释型语言(DSL)
3. 核心脚色

脚色作用AbstractExpression定义解释操作的抽象接口(Interpret())TerminalExpression实现基本语法元素的解释逻辑(闭幕符)NonTerminalExpression处理复合语法结构的解释逻辑(非闭幕符)Context存储解释器全局状态和变量情况Client构建语法树并触发解释过程 4. 类图


  1. @startuml
  2. interface Expression {
  3.     + Interpret(ctx Context) int
  4. }
  5. class Number {
  6.     - value: int
  7.     + Interpret()
  8. }
  9. class Add {
  10.     - left: Expression
  11.     - right: Expression
  12.     + Interpret()
  13. }
  14. class Subtract {
  15.     - left: Expression
  16.     - right: Expression
  17.     + Interpret()
  18. }
  19. class Context {
  20.     - variables: map[string]int
  21.     + GetVariable()
  22.     + SetVariable()
  23. }
  24. Expression <|-- Number
  25. Expression <|-- Add
  26. Expression <|-- Subtract
  27. Client --> Expression
  28. Client --> Context
  29. note right of Expression::Interpret
  30.     递归调用子表达式解释方法
  31.     实现语法树的深度优先遍历
  32. end note
  33. @enduml
复制代码
二、特点分析

优点

  • 扩展灵活:新增表达式范例只需添加新类
  • 结构清晰:语法规则与实验逻辑解耦
  • 范畴适配:可定制范畴专用语言解释器
缺点

  • 维护成本:复杂文法导致类数量膨胀
  • 性能损耗:递归解析影响实验效率
  • 适用局限:恰当语法规则稳定的场景
三、适用场景

1. 金融公式引擎

  1. type Formula interface {
  2.     Eval(ctx *FinanceContext) float64
  3. }
  4. type ROIFormula struct { // 投资回报率公式
  5.     Invest  Formula
  6.     Revenue Formula
  7. }
  8. func (f *ROIFormula) Eval(ctx *FinanceContext) float64 {
  9.     return (f.Revenue.Eval(ctx) - f.Invest.Eval(ctx)) / f.Invest.Eval(ctx)
  10. }
复制代码
2. 智能合约解析

  1. type ContractClause interface {
  2.     Execute(ledger *BlockchainLedger)
  3. }
  4. type TransferClause struct { // 资产转移条款
  5.     From   string
  6.     To     string
  7.     Amount Formula
  8. }
复制代码
3. 业务规则引擎

  1. type Rule interface {
  2.     Match(ctx *BusinessContext) bool
  3. }
  4. type CompositeRule struct { // 组合规则
  5.     Rules []Rule
  6.     Op    LogicalOperator
  7. }
复制代码
四、Go语言实现示例


完整实现代码

  1. package interpreter
  2. import "fmt"
  3. // 抽象表达式
  4. type BooleanExp interface {
  5.         Evaluate(ctx *Context) bool
  6. }
  7. // 终结符表达式
  8. type VariableExp struct {
  9.         name string
  10. }
  11. func (v *VariableExp) Evaluate(ctx *Context) bool {
  12.         return ctx.Lookup(v.name)
  13. }
  14. // 非终结符表达式
  15. type AndExp struct {
  16.         left, right BooleanExp
  17. }
  18. func (a *AndExp) Evaluate(ctx *Context) bool {
  19.         return a.left.Evaluate(ctx) && a.right.Evaluate(ctx)
  20. }
  21. type OrExp struct {
  22.         left, right BooleanExp
  23. }
  24. func (o *OrExp) Evaluate(ctx *Context) bool {
  25.         return o.left.Evaluate(ctx) || o.right.Evaluate(ctx)
  26. }
  27. // 上下文
  28. type Context struct {
  29.         variables map[string]bool
  30. }
  31. func NewContext() *Context {
  32.         return &Context{
  33.                 variables: make(map[string]bool),
  34.         }
  35. }
  36. func (c *Context) Assign(name string, value bool) {
  37.         c.variables[name] = value
  38. }
  39. func (c *Context) Lookup(name string) bool {
  40.         return c.variables[name]
  41. }
  42. // 客户端使用
  43. func Example() {
  44.         ctx := NewContext()
  45.         ctx.Assign("A", true)
  46.         ctx.Assign("B", false)
  47.         exp := &OrExp{
  48.                 left:  &VariableExp{"A"},
  49.                 right: &AndExp{
  50.                         left:  &VariableExp{"B"},
  51.                         right: &VariableExp{"C"},
  52.                 },
  53.         }
  54.         fmt.Println(exp.Evaluate(ctx)) // 输出: true
  55. }
复制代码
实验结果

  1. === RUN   TestExample
  2. true
  3. --- PASS: TestExample (0.00s)
  4. PASS
复制代码
五、高级应用

1. 表达式缓存优化

  1. type CachedExpression struct {
  2.     exp     BooleanExp
  3.     cache   map[*Context]bool
  4.     rwMutex sync.RWMutex
  5. }
  6. func (c *CachedExpression) Evaluate(ctx *Context) bool {
  7.     c.rwMutex.RLock()
  8.     if val, exists := c.cache[ctx]; exists {
  9.         c.rwMutex.RUnlock()
  10.         return val
  11.     }
  12.     c.rwMutex.RUnlock()
  13.     val := c.exp.Evaluate(ctx)
  14.    
  15.     c.rwMutex.Lock()
  16.     c.cache[ctx] = val
  17.     c.rwMutex.Unlock()
  18.    
  19.     return val
  20. }
复制代码
2. 并行解释器

  1. type ParallelInterpreter struct {
  2.     expressions []BooleanExp
  3.     workerPool  chan struct{}
  4. }
  5. func (p *ParallelInterpreter) EvalAll(ctx *Context) []bool {
  6.     results := make([]bool, len(p.expressions))
  7.     var wg sync.WaitGroup
  8.    
  9.     for i, exp := range p.expressions {
  10.         p.workerPool <- struct{}{}
  11.         wg.Add(1)
  12.         
  13.         go func(idx int, e BooleanExp) {
  14.             defer wg.Done()
  15.             results[idx] = e.Evaluate(ctx)
  16.             <-p.workerPool
  17.         }(i, exp)
  18.     }
  19.    
  20.     wg.Wait()
  21.     return results
  22. }
复制代码
六、与其他模式对比

模式核心区别典型应用场景组合模式树形结构 vs 语法树UI组件嵌套访问者模式状态遍历 vs 语法解析编译器优化策略模式算法选择 vs 语法解释支付方式选择 七、实现建议


  • 文法分层:使用EBNF定义语法规范
    1. // 语法定义示例
    2. type Grammar struct {
    3.     Productions map[string][]ProductionRule
    4. }
    复制代码
  • 错误恢复:实现语法错误检测机制
    1. type SyntaxError struct {
    2.     Position int
    3.     Message  string
    4. }
    5. func (e *SyntaxError) Error() string {
    6.     return fmt.Sprintf("[%d] %s", e.Position, e.Message)
    7. }
    复制代码
  • 内存管理:采用Flyweight模式共享闭幕符
    1. var terminalPool = sync.Pool{
    2.     New: func() interface{} {
    3.         return &TerminalExp{name: ""}
    4.     },
    5. }
    复制代码
  • 性能监控:集成运行时指标采集
    1. type MetricsInterceptor struct {
    2.     evalDuration  prometheus.Histogram
    3.     parseDuration prometheus.Histogram
    4. }
    复制代码
八、典型应用


  • 规则引擎:风控体系的条件判断
  • 查询语言:数据库SQL解析器
  • 编译前端:编程语言的词法/语法分析
  • 工业控制:PLC指令解释实验
在Go语言中实践建议:


  • 使用接口组合实现表达式扩展
  • 结合text/scanner实现词法分析
  • 采用sync.Pool优化高频表达式对象
  • 通过go/ast包实现复杂语法树操作

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表