From c988ffc8ff0a7402f7f2c8824bb41764ea41586e Mon Sep 17 00:00:00 2001 From: Edward Date: Tue, 5 May 2020 14:44:57 +0800 Subject: [PATCH] finish interpreter patten --- README.md | 35 ++--- behavior/08_interpreter/README.md | 3 +- behavior/08_interpreter/interpreter.go | 146 ++++++++++++++---- .../08_interpreter/interpreter_caculator.go | 59 ++++--- behavior/08_interpreter/interpreter_test.go | 23 ++- 5 files changed, 185 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 327302f..9728491 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Go语言设计模式示例集合(Go Patterns Examples) +# Golang工程模式示例集合(Go Patterns Examples) **包括了[go-patterns](https://github.com/tmrts/go-patterns) 和[golang-design-pattern](https://github.com/senghoo/golang-design-pattern)中的全部模式** @@ -9,14 +9,14 @@ **这些模式不是你总结的,也不是我的总结的,如果是你的写的,你可以按照自己的喜欢的感觉给这些套路取名字,让别人去费劲想。** -## 姿势 +## 姿势 Ways + 所谓模式就是套路,如功夫,招有定式 + 学习模式,就是学习套路,弄清楚套路要解决的目标场景,这很重要. + 这里就是以实际代码示例展示设计模式,通俗易懂 + 除了常见的23种普适的设计模式,Go也有一些属于自己的模式 -## 行为型模式 +## 行为型模式 Behavior Patterns + [x] [中介者模式(Mediator)](./behavior/01_mediator) + [x] [闭包选项模式(Function Option)](./behavior/02_option) @@ -32,7 +32,7 @@ + [x] [职责链模式(Chain of Responsibility)](./behavior/06_chain_of_responsibility) -## 创建型模式 +## 创建型模式 Creation Patterns + [x] [New模式(New)](./creation/01_new) + [x] [简单工厂模式(Simple Factory)](./creation/02_simple_factory) @@ -44,7 +44,7 @@ + [x] [原型模式(Prototype)](./creation/07_prototype) -## 结构型模式 +## 结构型模式 Structure Patterns + [x] [外观模式(Facade)](./structure/01_facade) + [x] [适配器模式(Adapter)](./structure/02_adapter) @@ -54,7 +54,7 @@ + [x] [装饰器模式(Decorator)](./structure/06_decorator) + [x] [代理模式(Proxy)](./structure/07_proxy) -## Go More +## 更多 Go More + [x] [发布订阅模式(Pub-Sub)](./gomore/01_messages) + [x] [时差模式(Time Profile)](./gomore/02_profiles) @@ -72,24 +72,15 @@ ## 参考资料(Design patters Articles) -[go-patterns](https://github.com/crazybber/go-patterns) - -[design-pattern-tutorial](https://www.runoob.com/design-pattern/design-pattern-tutorial.html) - -[golang-design-pattern](https://github.com/senghoo/golang-design-pattern) - -[design_pattern](http://c.biancheng.net/design_pattern) - -[go-resiliency](https://github.com/eapache/go-resiliency) - -[Behavioral](https://github.com/AlexanderGrom/go-patterns/tree/master/Behavioral) - -[go-patterns](https://github.com/sevenelevenlee/go-patterns) - -[go_design_pattern](https://github.com/monochromegane/go_design_pattern) +| Patterns | Design Patterns | Status | +|:-------:|:----------- |:------:| +| [go-patterns](https://github.com/crazybber/go-patterns) | [design-pattern-tutorial](https://www.runoob.com/design-pattern/design-pattern-tutorial.html) |p| +| [design_pattern](http://c.biancheng.net/design_pattern)|[golang-design-pattern](https://github.com/senghoo/golang-design-pattern) |p| +[go-resiliency](https://github.com/eapache/go-resiliency) | [Behavioral](https://github.com/AlexanderGrom/go-patterns/tree/master/Behavioral)|v| +| [go-patterns](https://github.com/sevenelevenlee/go-patterns) | [go_design_pattern](https://github.com/monochromegane/go_design_pattern)|p| -## 更多 +## 更多 More 需要重新温习下Go基础?看这里 diff --git a/behavior/08_interpreter/README.md b/behavior/08_interpreter/README.md index d776d05..a57f7b3 100644 --- a/behavior/08_interpreter/README.md +++ b/behavior/08_interpreter/README.md @@ -1,6 +1,6 @@ # 解释器模式 -解释器模式就是自己定一套规则、语言、表达方式,也就是所谓的DSL(Domain Specific Language),然后按照定义解析执行DSL,常见的自定义协议,私有协议,就是一个中解释器模式的概念,使用者按照协议的规则做事。 +解释器模式的本质是就是自己定一套规则、语言、表达方式,也就是所谓的DSL(Domain Specific Language),然后按照定义解析执行DSL,常见的自定义协议,私有协议,就是一个中解释器模式的概念,使用者按照协议的规则做事。 解释器模式的意义在于,它分离多种复杂功能的实现,每个功能只需关注自身的解释。 @@ -15,5 +15,4 @@ A "->" B 表示 A说,B听,此时B不能发言。 A "<-" B 表示 B说,A听,此时B不能发言。 A "<->" B 表示 A 和 B 可以自由发言。 -A "-" B 表示 A 和 B 都不能发言,只能倾听。 diff --git a/behavior/08_interpreter/interpreter.go b/behavior/08_interpreter/interpreter.go index 92ed3f1..43d4f4a 100644 --- a/behavior/08_interpreter/interpreter.go +++ b/behavior/08_interpreter/interpreter.go @@ -1,69 +1,147 @@ package interpreter import ( - "strconv" + "fmt" "strings" ) -//用会议交流的例子 +//用会议交流的例子,规则如下: // A表示左边发言者,B表示右边发言者 // A "->" B 表示 A说,B听,此时B不能发言。 // A "<-" B 表示 B说,A听,此时B不能发言。 // A "<->" B 表示 A 和 B 可以自由发言。 -// A "-" B 表示 A 和 B 都不能发言,只能倾听。 - - +//IActionInterpret 解释器 type IActionInterpret interface { Interpret() } -//Speaker 发言者 -type Speaker struct { - Name string - Age int +//SpeakerUnit 每个参与动作的单元都是,会议发言者 +type SpeakerUnit struct { + Name string + CanSpeak bool //每个参会者有两种基本的行为,发言或者安静 +} + +//Interpret 解释自己的基本行为 +func (s *SpeakerUnit) Interpret() { + if s.CanSpeak { + fmt.Println("i'm", s.Name, "i’m speaking") + return + } + fmt.Println("i'm", s.Name, "already silent") +} + +//LeftSpeakAction :A "->" B 表示 A说,B听,此时B不能发言。 +type LeftSpeakAction struct { + leftSpeaker, rightSpeaker IActionInterpret +} + +//Interpret 解释执行 +func (l *LeftSpeakAction) Interpret() { + + l.leftSpeaker.Interpret() + l.rightSpeaker.Interpret() } -func (s *Speaker) Interpret() { - +//RightSpeakAction :A "<-" B 表示 B说,A听,此时B不能发言。 +type RightSpeakAction struct { + leftSpeaker, rightSpeaker IActionInterpret } -//LeftIntroduce A向B介绍自己 -type LeftIntroduce struct { - leftSpeaker, rightSpeaker Speaker +//Interpret 解释执行 +func (r *RightSpeakAction) Interpret() { + r.leftSpeaker.Interpret() + r.rightSpeaker.Interpret() } - -func (l *LeftIntroduce) Interpret() { - +//BothSpeakAction : A "<->" B 表示 A 和 B 可以自由发言。 +type BothSpeakAction struct { + leftSpeaker, rightSpeaker IActionInterpret } -//RightIntroduce B向A介绍自己 -type RightIntroduce struct { - leftSpeaker, rightSpeaker Speaker +//Interpret 解释执行 +func (b *BothSpeakAction) Interpret() { + b.leftSpeaker.Interpret() + b.rightSpeaker.Interpret() } -func (n *MinNode) Interpret() int { - return n.left.Interpret() - n.right.Interpret() -} - -//标识解析器 +//SignParser 我们自己的DSL解析器 type SignParser struct { - actionsMark []string + actionUnits []string //要解析的内容 + result IActionInterpret //上一个也是解释器单元 } -//Parse 标识解析器进行解析 -func (p *SignParser) Parse(exp string) { - p.exp = strings.Split(exp, " ") +//解析 -> +func (s *SignParser) newLeftSpeakAction() IActionInterpret { - s := p.actionsMark[0] - for len(s) >0 { - switch s.actionsMark[0] { - - } + left := &SpeakerUnit{ + Name: s.actionUnits[0], + CanSpeak: true, + } + right := &SpeakerUnit{ + Name: s.actionUnits[2], + } + return &LeftSpeakAction{ + leftSpeaker: left, + rightSpeaker: right, } } +//解析 <- +func (s *SignParser) newRightSpeakAction() IActionInterpret { + left := &SpeakerUnit{ + Name: s.actionUnits[0], + } + right := &SpeakerUnit{ + Name: s.actionUnits[2], + CanSpeak: true, + } + return &LeftSpeakAction{ + leftSpeaker: left, + rightSpeaker: right, + } +} +//解析 <-> +func (s *SignParser) newBothSpeakAction() IActionInterpret { + + left := &SpeakerUnit{ + Name: s.actionUnits[0], + CanSpeak: true, + } + right := &SpeakerUnit{ + Name: s.actionUnits[2], + CanSpeak: true, + } + return &LeftSpeakAction{ + leftSpeaker: left, + rightSpeaker: right, + } +} + +//Parse 标识解析器进行解析,exp就是要解释的内容 +func (s *SignParser) Parse(exp string) { + + s.actionUnits = strings.Split(exp, " ") //单元分割符 + + switch s.actionUnits[1] { + case "->": + s.result = s.newLeftSpeakAction() + case "<-": + s.result = s.newRightSpeakAction() + case "<->": + s.result = s.newBothSpeakAction() + default: + fmt.Println("some error raised") + } + +} + +//Result 就是两边正确执行了动作 +func (s *SignParser) Result() { + + s.result.Interpret() + +} diff --git a/behavior/08_interpreter/interpreter_caculator.go b/behavior/08_interpreter/interpreter_caculator.go index 9418ce6..e2dc4e3 100644 --- a/behavior/08_interpreter/interpreter_caculator.go +++ b/behavior/08_interpreter/interpreter_caculator.go @@ -5,40 +5,54 @@ import ( "strings" ) -type Node interface { +//解释自定义的加减法运算 +//输入:字符串 +//输出:整数值 +//将一个包含加减运算的字符串,正常解析出结果 + +//Element 每个元素的解释接口 +type Element interface { Interpret() int } -type ValNode struct { +//ValElement 值节点 +type ValElement struct { val int } -func (n *ValNode) Interpret() int { +//Interpret 值解析单元的返回值 +func (n *ValElement) Interpret() int { return n.val } -type AddNode struct { - left, right Node +//AddOperate Operation(+) +type AddOperate struct { + left, right Element } -func (n *AddNode) Interpret() int { +//Interpret AddOperate +func (n *AddOperate) Interpret() int { return n.left.Interpret() + n.right.Interpret() } -type MinNode struct { - left, right Node +//MinOperate Operation(-) +type MinOperate struct { + left, right Element } -func (n *MinNode) Interpret() int { +//Interpret MinOperate +func (n *MinOperate) Interpret() int { return n.left.Interpret() - n.right.Interpret() } +//Parser machine type Parser struct { exp []string index int - prev Node + prev Element } +//Parse content func (p *Parser) Parse(exp string) { p.exp = strings.Split(exp, " ") @@ -48,39 +62,40 @@ func (p *Parser) Parse(exp string) { } switch p.exp[p.index] { case "+": - p.prev = p.newAddNode() + p.prev = p.newAddOperte() case "-": - p.prev = p.newMinNode() + p.prev = p.newMinOperte() default: - p.prev = p.newValNode() + p.prev = p.newValElement() } } } -func (p *Parser) newAddNode() Node { +func (p *Parser) newAddOperte() Element { p.index++ - return &AddNode{ + return &AddOperate{ left: p.prev, - right: p.newValNode(), + right: p.newValElement(), } } -func (p *Parser) newMinNode() Node { +func (p *Parser) newMinOperte() Element { p.index++ - return &MinNode{ + return &MinOperate{ left: p.prev, - right: p.newValNode(), + right: p.newValElement(), } } -func (p *Parser) newValNode() Node { +func (p *Parser) newValElement() Element { v, _ := strconv.Atoi(p.exp[p.index]) p.index++ - return &ValNode{ + return &ValElement{ val: v, } } -func (p *Parser) Result() Node { +//Result of parsing result +func (p *Parser) Result() Element { return p.prev } diff --git a/behavior/08_interpreter/interpreter_test.go b/behavior/08_interpreter/interpreter_test.go index 3919e6c..5ee8166 100644 --- a/behavior/08_interpreter/interpreter_test.go +++ b/behavior/08_interpreter/interpreter_test.go @@ -2,7 +2,28 @@ package interpreter import "testing" -func TestInterpreter(t *testing.T) { +func TestMeetingActionSignInterpreter(t *testing.T) { + + p := &SignParser{} + + p.Parse("rose -> tom") + p.Result() + + p.Parse("rose <-> tom") + p.Result() + + p.Parse("rose <- tom") + + p.Result() + + //should error + p.Parse("rose + tom") + + p.Result() + +} + +func TestCalculatorInterpreter(t *testing.T) { p := &Parser{} p.Parse("1 + 2 + 3 - 4 + 5 - 6") res := p.Result().Interpret()