mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-22 03:46:03 +03:00
add code content for state pattern
This commit is contained in:
parent
a7bc893c4b
commit
6a72ca4b8e
@ -16,3 +16,9 @@ A "->" B 表示 A说,B听,此时B不能发言。
|
|||||||
A "<-" B 表示 B说,A听,此时B不能发言。
|
A "<-" B 表示 B说,A听,此时B不能发言。
|
||||||
A "<->" B 表示 A 和 B 可以自由发言。
|
A "<->" B 表示 A 和 B 可以自由发言。
|
||||||
|
|
||||||
|
解释器模式中的关键角色:
|
||||||
|
|
||||||
|
1. 表达式 一般就是一串带解析的内容流,可能是字符串,也可能是字节流等
|
||||||
|
2. 表达式解释类,一般就是解析器
|
||||||
|
3. 表达式子类型解析器,对于表达式中解析到的不同情况,交给不同的解析子类去处理。
|
||||||
|
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
# 状态模式
|
# 状态模式
|
||||||
|
|
||||||
状态模式的目的就是设计一个状态机,用状态的改变/流转驱动行为变化,前提是需要知道所有的状态,否则,该模式有益于根据已知状态扩展行为。
|
状态模式的目的就是设计一个状态机,用状态的改变/流转驱动行为变化,前提是需要知道所有的状态,否则,该模式有益于根据已知状态扩展行为。
|
||||||
|
|
||||||
|
|
||||||
|
我们打游戏,游戏角色的拟人状态有:走,跑,原地不动,休息
|
||||||
|
|
||||||
|
状态模式的关键角色:
|
||||||
|
Context: 拥有多种状态的上下文对象(struct), 持有状态属性State
|
||||||
|
State: 封装特定状态行为的interface
|
||||||
|
ConcreteState: 具体的状态,继承接口State,不同的状态执行Context的不同行为
|
||||||
|
@ -1,96 +1,5 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import "fmt"
|
//IRobot 代表机器人
|
||||||
|
type IRobot interface {
|
||||||
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{}
|
|
||||||
}
|
}
|
||||||
|
48
behavior/10_state/state_clock.go
Normal file
48
behavior/10_state/state_clock.go
Normal file
@ -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..."
|
||||||
|
}
|
@ -1,6 +1,27 @@
|
|||||||
package state
|
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()
|
ctx := NewDayContext()
|
||||||
todayAndNext := func() {
|
todayAndNext := func() {
|
||||||
ctx.Today()
|
ctx.Today()
|
||||||
|
96
behavior/10_state/state_weeks.go
Normal file
96
behavior/10_state/state_weeks.go
Normal file
@ -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{}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user