状态模式

概念

在状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中, 可以把复杂的逻辑简化。当然, 如果这个状态判断很简单,就没有必要使用'状态模式'了。

UML类图

statepattern.png

使用场景和优缺点

使用场景

代码中包含大量与对象状态有关的条件语句, 当一个对象的行为取决于他的状态, 并且他必须在运行时刻根据状态改变他的行为时, 既可以考虑使用状态模式了。

优点

  • 行为和状态解耦

将与特定状态相关的行为局部话, 并且将不同的状态的行为分割开来。

  • 易扩展

将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为

  • 简化逻辑
  1. 消除了庞大的条件分支语句, 将某一类状态的行为放到同一个类中。
  2. 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点

  • 状态模式的使用必然会增加系统类和对象的个数
  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
  • 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码

代码实现


package main

import (
    "fmt"
)

type IState interface {
    WriteProgram(work Work)
}

type Work struct {
    State      IState
    Hour       float64
    TaskFinish bool
}

func (w *Work) SetState(state IState) {
    w.State = state
}
func (w *Work) WriteProgram() {
    w.State.WriteProgram(*w)
}


type ForenoonState struct {
}

func (f *ForenoonState) WriteProgram(work Work) {
    if work.Hour < 12 {
        fmt.Printf("当前时间:%v点,上午工作 精神百倍", work.Hour)
    } else {
        work.SetState(&NoonState{})
        work.WriteProgram()
    }
}

type NoonState struct {
}

func (n *NoonState) WriteProgram(work Work) {
    if work.Hour < 13 {
        fmt.Printf("当前时间:%v点,饿了 午饭 犯困 午休", work.Hour)
    } else {
        work.SetState(&AfternoonState{})
        work.WriteProgram()
    }
}

type AfternoonState struct {
}

func (a *AfternoonState) WriteProgram(work Work) {
    if work.Hour < 17 {
        fmt.Printf("当前时间:%v点,下午状态还不错 继续努力", work.Hour)
    } else {
        work.SetState(&EveningState{})
        work.WriteProgram()
    }
}

type EveningState struct {
}

func (e *EveningState) WriteProgram(work Work) {
    if work.TaskFinish {
        work.SetState(&RestState{})
        work.WriteProgram()
    } else {
        if work.Hour < 21 {
            fmt.Printf("当前时间:%v点,加班哦 疲累至极", work.Hour)
        } else {
            work.SetState(&SleepState{})
            work.WriteProgram()
        }
    }
}

type RestState struct {
}

func (r *RestState) WriteProgram(work Work) {
    fmt.Printf("当前时间:%v点,下班回家了", work.Hour)
}

type SleepState struct {
}

func (s *SleepState) WriteProgram(work Work) {
    fmt.Printf("当前时间:%v点,不行了 睡着了", work.Hour)
}

func main() {
    //状态模式
    emergencyProject := Work{State: &ForenoonState{}}
    emergencyProject.Hour = 9
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 10
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 12
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 13
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 14
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 17

    emergencyProject.TaskFinish = true

    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 19
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 22
    emergencyProject.WriteProgram()
    fmt.Println()
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容