From 6a72ca4b8ea75583d5801546d9eb600b1c0eb4aa Mon Sep 17 00:00:00 2001 From: Edward Date: Tue, 5 May 2020 22:43:54 +0800 Subject: [PATCH] add code content for state pattern --- behavior/08_interpreter/README.md | 6 ++ behavior/10_state/README.md | 8 +++ behavior/10_state/state.go | 95 +----------------------------- behavior/10_state/state_clock.go | 48 ++++++++++++++++ behavior/10_state/state_test.go | 23 +++++++- behavior/10_state/state_weeks.go | 96 +++++++++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 94 deletions(-) create mode 100644 behavior/10_state/state_clock.go create mode 100644 behavior/10_state/state_weeks.go diff --git a/behavior/08_interpreter/README.md b/behavior/08_interpreter/README.md index a57f7b3..0e0d671 100644 --- a/behavior/08_interpreter/README.md +++ b/behavior/08_interpreter/README.md @@ -16,3 +16,9 @@ A "->" B 表示 A说,B听,此时B不能发言。 A "<-" B 表示 B说,A听,此时B不能发言。 A "<->" B 表示 A 和 B 可以自由发言。 +解释器模式中的关键角色: + + 1. 表达式 一般就是一串带解析的内容流,可能是字符串,也可能是字节流等 + 2. 表达式解释类,一般就是解析器 + 3. 表达式子类型解析器,对于表达式中解析到的不同情况,交给不同的解析子类去处理。 + diff --git a/behavior/10_state/README.md b/behavior/10_state/README.md index 11525ca..1b93947 100644 --- a/behavior/10_state/README.md +++ b/behavior/10_state/README.md @@ -1,3 +1,11 @@ # 状态模式 状态模式的目的就是设计一个状态机,用状态的改变/流转驱动行为变化,前提是需要知道所有的状态,否则,该模式有益于根据已知状态扩展行为。 + + +我们打游戏,游戏角色的拟人状态有:走,跑,原地不动,休息 + +状态模式的关键角色: + Context: 拥有多种状态的上下文对象(struct), 持有状态属性State + State: 封装特定状态行为的interface + ConcreteState: 具体的状态,继承接口State,不同的状态执行Context的不同行为 diff --git a/behavior/10_state/state.go b/behavior/10_state/state.go index 691158f..60c83fa 100644 --- a/behavior/10_state/state.go +++ b/behavior/10_state/state.go @@ -1,96 +1,5 @@ package state -import "fmt" - -type Week interface { - Today() - Next(*DayContext) -} - -type DayContext struct { - today Week -} - -func NewDayContext() *DayContext { - return &DayContext{ - today: &Sunday{}, - } -} - -func (d *DayContext) Today() { - d.today.Today() -} - -func (d *DayContext) Next() { - d.today.Next(d) -} - -type Sunday struct{} - -func (*Sunday) Today() { - fmt.Printf("Sunday\n") -} - -func (*Sunday) Next(ctx *DayContext) { - ctx.today = &Monday{} -} - -type Monday struct{} - -func (*Monday) Today() { - fmt.Printf("Monday\n") -} - -func (*Monday) Next(ctx *DayContext) { - ctx.today = &Tuesday{} -} - -type Tuesday struct{} - -func (*Tuesday) Today() { - fmt.Printf("Tuesday\n") -} - -func (*Tuesday) Next(ctx *DayContext) { - ctx.today = &Wednesday{} -} - -type Wednesday struct{} - -func (*Wednesday) Today() { - fmt.Printf("Wednesday\n") -} - -func (*Wednesday) Next(ctx *DayContext) { - ctx.today = &Thursday{} -} - -type Thursday struct{} - -func (*Thursday) Today() { - fmt.Printf("Thursday\n") -} - -func (*Thursday) Next(ctx *DayContext) { - ctx.today = &Friday{} -} - -type Friday struct{} - -func (*Friday) Today() { - fmt.Printf("Friday\n") -} - -func (*Friday) Next(ctx *DayContext) { - ctx.today = &Saturday{} -} - -type Saturday struct{} - -func (*Saturday) Today() { - fmt.Printf("Saturday\n") -} - -func (*Saturday) Next(ctx *DayContext) { - ctx.today = &Sunday{} +//IRobot 代表机器人 +type IRobot interface { } diff --git a/behavior/10_state/state_clock.go b/behavior/10_state/state_clock.go new file mode 100644 index 0000000..9283592 --- /dev/null +++ b/behavior/10_state/state_clock.go @@ -0,0 +1,48 @@ +// Package state is an example of the State Pattern. +package state + +//////////////////////////////// +//闹装有两种状态,震铃状态,非震铃状态 + +// MobileAlertStater provides a common interface for various states. +type MobileAlertStater interface { + Alert() string +} + +// MobileAlert implements an alert depending on its state. +type MobileAlert struct { + state MobileAlertStater +} + +// Alert returns a alert string +func (a *MobileAlert) Alert() string { + return a.state.Alert() +} + +// SetState changes state +func (a *MobileAlert) SetState(state MobileAlertStater) { + a.state = state +} + +// NewMobileAlert is the MobileAlert constructor. +func NewMobileAlert() *MobileAlert { + return &MobileAlert{state: &MobileAlertVibration{}} +} + +// MobileAlertVibration implements vibration alert +type MobileAlertVibration struct { +} + +// Alert returns a alert string +func (a *MobileAlertVibration) Alert() string { + return "vibrating humming ... vibrating humming...vibrating humming..." +} + +// MobileAlertSong implements beep alert +type MobileAlertSong struct { +} + +// Alert returns a alert string +func (a *MobileAlertSong) Alert() string { + return "sun rise ,get up ,get up get up..." +} diff --git a/behavior/10_state/state_test.go b/behavior/10_state/state_test.go index 1f4b989..a7d3724 100644 --- a/behavior/10_state/state_test.go +++ b/behavior/10_state/state_test.go @@ -1,6 +1,27 @@ package state -func ExampleWeek() { +import "testing" + +func TestState(t *testing.T) { + + expect := "vibrating humming ... vibrating humming...vibrating humming..." + + "vibrating humming ... vibrating humming...vibrating humming..." + + "sun rise ,get up ,get up get up..." + + mobile := NewMobileAlert() + + result := mobile.Alert() + result += mobile.Alert() + + mobile.SetState(&MobileAlertSong{}) + + result += mobile.Alert() + + if result != expect { + t.Errorf("Expect result to equal %s, but %s.\n", expect, result) + } +} +func TestWeeks(t *testing.T) { ctx := NewDayContext() todayAndNext := func() { ctx.Today() diff --git a/behavior/10_state/state_weeks.go b/behavior/10_state/state_weeks.go new file mode 100644 index 0000000..691158f --- /dev/null +++ b/behavior/10_state/state_weeks.go @@ -0,0 +1,96 @@ +package state + +import "fmt" + +type Week interface { + Today() + Next(*DayContext) +} + +type DayContext struct { + today Week +} + +func NewDayContext() *DayContext { + return &DayContext{ + today: &Sunday{}, + } +} + +func (d *DayContext) Today() { + d.today.Today() +} + +func (d *DayContext) Next() { + d.today.Next(d) +} + +type Sunday struct{} + +func (*Sunday) Today() { + fmt.Printf("Sunday\n") +} + +func (*Sunday) Next(ctx *DayContext) { + ctx.today = &Monday{} +} + +type Monday struct{} + +func (*Monday) Today() { + fmt.Printf("Monday\n") +} + +func (*Monday) Next(ctx *DayContext) { + ctx.today = &Tuesday{} +} + +type Tuesday struct{} + +func (*Tuesday) Today() { + fmt.Printf("Tuesday\n") +} + +func (*Tuesday) Next(ctx *DayContext) { + ctx.today = &Wednesday{} +} + +type Wednesday struct{} + +func (*Wednesday) Today() { + fmt.Printf("Wednesday\n") +} + +func (*Wednesday) Next(ctx *DayContext) { + ctx.today = &Thursday{} +} + +type Thursday struct{} + +func (*Thursday) Today() { + fmt.Printf("Thursday\n") +} + +func (*Thursday) Next(ctx *DayContext) { + ctx.today = &Friday{} +} + +type Friday struct{} + +func (*Friday) Today() { + fmt.Printf("Friday\n") +} + +func (*Friday) Next(ctx *DayContext) { + ctx.today = &Saturday{} +} + +type Saturday struct{} + +func (*Saturday) Today() { + fmt.Printf("Saturday\n") +} + +func (*Saturday) Next(ctx *DayContext) { + ctx.today = &Sunday{} +}