当前位置:首页 > 编程笔记 > 正文
已解决

《golang设计模式》第三部分·行为型模式-03-解释器模式(Interpreter)

来自网友在路上 178878提问 提问时间:2023-10-31 09:59:57阅读次数: 78

最佳答案 问答题库788位专家为你答疑解惑

文章目录

  • 1. 概述
    • 1.1 角色
    • 1.2 类图
    • 1.3 优缺点
  • 2. 代码示例
    • 2.1 设计
    • 2.2 代码
    • 2.3 类图

1. 概述

解释器模式(Interpreter)是用于表达语言语法树和封装语句解释(或运算)行为的对象。

1.1 角色

  • AbstractExpression(抽象表达式):具体表达式的一个抽象接口,交由具体子类进行具体解释
  • TerminalExpression(终结符表达式):实现文法中与终结符有关的解释操作
  • NonTerminalExpression(非终结符表达式):实现文法中与非终结符有关的解释操作
  • Context(上下文环境类):解释器上下文环境类
  • Client :持有上下文和抽象表达式,

1.2 类图

<style>#mermaid-svg-QtG0ZI4qkxg7Bm2a {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .error-icon{fill:#552222;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .marker.cross{stroke:#333333;}#mermaid-svg-QtG0ZI4qkxg7Bm2a svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a g.classGroup text{fill:#9370DB;fill:#131300;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a g.classGroup text .title{font-weight:bolder;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .nodeLabel,#mermaid-svg-QtG0ZI4qkxg7Bm2a .edgeLabel{color:#131300;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .label text{fill:#131300;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .classTitle{font-weight:bolder;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .node rect,#mermaid-svg-QtG0ZI4qkxg7Bm2a .node circle,#mermaid-svg-QtG0ZI4qkxg7Bm2a .node ellipse,#mermaid-svg-QtG0ZI4qkxg7Bm2a .node polygon,#mermaid-svg-QtG0ZI4qkxg7Bm2a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .divider{stroke:#9370DB;stroke:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a g.clickable{cursor:pointer;}#mermaid-svg-QtG0ZI4qkxg7Bm2a g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-QtG0ZI4qkxg7Bm2a g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .dashed-line{stroke-dasharray:3;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #compositionStart,#mermaid-svg-QtG0ZI4qkxg7Bm2a .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #compositionEnd,#mermaid-svg-QtG0ZI4qkxg7Bm2a .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #dependencyStart,#mermaid-svg-QtG0ZI4qkxg7Bm2a .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #dependencyStart,#mermaid-svg-QtG0ZI4qkxg7Bm2a .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #extensionStart,#mermaid-svg-QtG0ZI4qkxg7Bm2a .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #extensionEnd,#mermaid-svg-QtG0ZI4qkxg7Bm2a .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #aggregationStart,#mermaid-svg-QtG0ZI4qkxg7Bm2a .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a #aggregationEnd,#mermaid-svg-QtG0ZI4qkxg7Bm2a .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QtG0ZI4qkxg7Bm2a .edgeTerminals{font-size:11px;}#mermaid-svg-QtG0ZI4qkxg7Bm2a :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
Context
AbstractExpression
TerminalExpression
+Interpret(con:Context)
NoTerminalExpression
+Interpret(con:Context)
Client

1.3 优缺点

  • 优点
    • 可拓展性高,灵活
    • 易于实现简单的文法
  • 缺点
    • 可使用场景少
    • 对于复杂的文法较难维护
    • 会引起类膨胀

2. 代码示例

2.1 设计

需求:COS的设计

  • 定义一个上下文,用来对字串做表达前的处理。
    • 本例中只需要将字串切割成字符列表备用。
  • 定义一个抽象表达式
    • 它由加、减两、数值三个具体表达式分别实现
      • 只是一个表达式,被客户端组装之后才能显示它的实际作用。
  • 定义一个客户端
    • 持有上下文,意味着他可以实例化一个上下文来对COS的字串做表达前的处理。
    • 持有表达式,意味着它可以实例化并组装一个表达式

2.2 代码

  • 代码
package mainimport ("fmt""strconv""strings"
)// 定义一个抽象表达式
type Node interface {Interpreter() int
}// 定义终结表达式
type ValNode struct {val int
}func (v *ValNode) Interpreter() int {return v.val
}// 定义非终结表达式——加法
type AddNode struct {left  Noderight Node
}func (a *AddNode) Interpreter() int {return a.left.Interpreter() + a.right.Interpreter()
}// 定义非终结表达式——减法
type SubNode struct {left  Noderight Node
}func (s *SubNode) Interpreter() int {return s.left.Interpreter() - s.right.Interpreter()
}// 定义上下文
type Context struct {exp   []stringindex int
}// 它的方法负解释前的所有处理
func (c *Context) GetList(exp string) {c.exp = strings.Split(exp, " ")
}// 定义客户端,它持有上下文和解释器
type Client struct {context Contextprev    Node
}// 构造表达式
func (p *Client) CreateNode(expString string) Node {p.context = Context{}p.context.GetList(expString)for {if p.context.index >= len(p.context.exp) {return p.prev}switch p.context.exp[p.context.index] {case "+":p.prev = p.CreateAddNode()case "-":p.prev = p.CreateSubNode()default:p.prev = p.CreateValNode()}}}// 三个方法用来创建node并参与表达式的拼装
func (p *Client) CreateAddNode() Node {p.context.index++return &AddNode{left: p.prev, right: p.CreateValNode()}
}func (p *Client) CreateSubNode() Node {p.context.index++return &SubNode{left: p.prev, right: p.CreateValNode()}
}func (p *Client) CreateValNode() Node {v, _ := strconv.Atoi(p.context.exp[p.context.index])p.context.index++return &ValNode{v}
}func main() {//实例化一个客户端p := &Client{}//拼装表达式node := p.CreateNode("1 + 5 - 3")//调用表达式得到结果result := node.Interpreter()//验证结果(实际应用中应该由客户端验证,我们这里打印出来口算验证一下好了。)fmt.Println(result)
}
  • 输出
3

2.3 类图

<style>#mermaid-svg-8Vectv96zCfB35hN {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8Vectv96zCfB35hN .error-icon{fill:#552222;}#mermaid-svg-8Vectv96zCfB35hN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8Vectv96zCfB35hN .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-8Vectv96zCfB35hN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8Vectv96zCfB35hN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8Vectv96zCfB35hN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8Vectv96zCfB35hN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8Vectv96zCfB35hN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8Vectv96zCfB35hN .marker.cross{stroke:#333333;}#mermaid-svg-8Vectv96zCfB35hN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8Vectv96zCfB35hN g.classGroup text{fill:#9370DB;fill:#131300;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-8Vectv96zCfB35hN g.classGroup text .title{font-weight:bolder;}#mermaid-svg-8Vectv96zCfB35hN .nodeLabel,#mermaid-svg-8Vectv96zCfB35hN .edgeLabel{color:#131300;}#mermaid-svg-8Vectv96zCfB35hN .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-8Vectv96zCfB35hN .label text{fill:#131300;}#mermaid-svg-8Vectv96zCfB35hN .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-8Vectv96zCfB35hN .classTitle{font-weight:bolder;}#mermaid-svg-8Vectv96zCfB35hN .node rect,#mermaid-svg-8Vectv96zCfB35hN .node circle,#mermaid-svg-8Vectv96zCfB35hN .node ellipse,#mermaid-svg-8Vectv96zCfB35hN .node polygon,#mermaid-svg-8Vectv96zCfB35hN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8Vectv96zCfB35hN .divider{stroke:#9370DB;stroke:1;}#mermaid-svg-8Vectv96zCfB35hN g.clickable{cursor:pointer;}#mermaid-svg-8Vectv96zCfB35hN g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-8Vectv96zCfB35hN g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-8Vectv96zCfB35hN .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-8Vectv96zCfB35hN .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-8Vectv96zCfB35hN .dashed-line{stroke-dasharray:3;}#mermaid-svg-8Vectv96zCfB35hN #compositionStart,#mermaid-svg-8Vectv96zCfB35hN .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #compositionEnd,#mermaid-svg-8Vectv96zCfB35hN .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #dependencyStart,#mermaid-svg-8Vectv96zCfB35hN .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #dependencyStart,#mermaid-svg-8Vectv96zCfB35hN .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #extensionStart,#mermaid-svg-8Vectv96zCfB35hN .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #extensionEnd,#mermaid-svg-8Vectv96zCfB35hN .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #aggregationStart,#mermaid-svg-8Vectv96zCfB35hN .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN #aggregationEnd,#mermaid-svg-8Vectv96zCfB35hN .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8Vectv96zCfB35hN .edgeTerminals{font-size:11px;}#mermaid-svg-8Vectv96zCfB35hN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
Client
+context:Context
+prev:Node
+CreateNode(expString string) : Node
+CreateAddNode() : Node
+CreateSubNode() : Node
+CreateValNode() : Node
Context
+exp:[]string
+index:int
+GetList(exp string)
«interface»
Node
+Interpreter() : int
ValNode
+val:int
+Interpreter() : int
AddNode
+left:Node
+right:Node
+Interpreter() : int
SubNode
+left:Node
+right:Node
+Interpreter() : int
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"《golang设计模式》第三部分·行为型模式-03-解释器模式(Interpreter)":http://eshow365.cn/6-28523-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!