首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Golang语言情怀-第32期 Go 语言设计模式 状态

Golang语言情怀-第32期 Go 语言设计模式 状态

作者头像
李海彬
发布2021-02-05 16:22:20
发布2021-02-05 16:22:20
5020
举报
文章被收录于专栏:Golang语言社区Golang语言社区

什么是状态模式

状态模式允许对象在内部状态改变时,改变它的行为。这样对象看起来好像是 修改了它的类

解决了什么问题

状态模式解决了对象的行为依赖它的状态(属性)的问题。如果代码中包含大量与对象 状态有关的条件语句时,可以使用状态模式。

优点

  • 封装了转换规则
  • 将所有与某个状态有关的行为放到一个类中,并且可方便的新增状态
  • 允许状态转换逻辑和状态对象合成一体,而不是巨大的条件语句块

缺点

  • 状态模式的使用,必然会增加系统类和对象的个数
  • 状态模式的结构与实现都比较复杂,如果使用不当会导致系统混乱

实现图

代码实现 1

1.实现一个状态保存类

状态保存类用于保存当前状态。

代码语言:javascript
复制
//Context 状态保存 类
type Context struct {
    state State
}

//NewContext 实例化状态保存类
func NewContext() *Context {
    return &Context{
        state: nil,
    }
}

//SetState 设置状态保存类当前的状态
func (c *Context) SetState(s State) {
    c.state = s
}

//GetState 获取状态保存类当前的状态
func (c *Context) GetState() State {
    return c.state
}

2. 定义状态类接口

代码语言:javascript
复制
//State 状态接口
type State interface {
    DoAction(context *Context)
    ToString() string
}

3. 实现状态类

代码语言:javascript
复制
//StartState 开始状态类
type StartState struct{}

//NewStatartState 实例化开始状态类
func NewStatartState() *StartState {
    return &StartState{}
}

//DoAction 开始状态类的DoAction,实现State接口
func (start *StartState) DoAction(context *Context) {
    fmt.Println("Now is start state")
    context.state = start
}

//ToString 返回开始状态类名称
func (start *StartState) ToString() string {
    return "Start state"
}

测试

代码语言:javascript
复制
context := NewContext()

startState := NewStatartState()
startState.DoAction(context)
fmt.Println(context.GetState().ToString())

stopState := NewStopState()
stopState.DoAction(context)
fmt.Println(context.GetState().ToString())

代码实现 2

公共类

代码语言:javascript
复制
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)
}

子类

代码语言:javascript
复制
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{}
}

测试

代码语言:javascript
复制
func ExampleWeek() {
    fmt.Println(111)
    ctx := NewDayContext()
    todayAndNext := func() {
        ctx.Today()
        ctx.Next()
    }

    for i := 0; i < 8; i++ {
        todayAndNext()
    }
    // Output:
    // Sunday
    // Monday
    // Tuesday
    // Wednesday
    // Thursday
    // Friday
    // Saturday
    // Sunday
}

参考资料:

Go语言设计模式

https://studygolang.com/articles/31113

设计模式

https://blog.csdn.net/m0_37645820/article/details/106028905

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言情怀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是状态模式
  • 解决了什么问题
    • 优点
    • 缺点
  • 代码实现 1
    • 1.实现一个状态保存类
    • 2. 定义状态类接口
    • 3. 实现状态类
  • 代码实现 2
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档