设计模式go语言实现----状态模式State

1 定义

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

模式动机:
当控制一个对象状态转换的条件表达式过于复杂时,将状态的判断逻辑转移道表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

UML类图:
设计模式go语言实现----状态模式State
状态模式包含如下几个角色:

  • Context(环境类):维护一个ConcreteState子类的实例,这个实例定义当前的状态
  • State(抽象状态类):定义一个接口以封装与Context的一个特定状态相关的行为
  • ConcreteState(具体状态类):每一个子类实现一个与Context的一个状态相关的行为

下面以我们工作的状态(随着时间的变化,我们的工装状态是会不断变化的)为例,其UML类图如下:
设计模式go语言实现----状态模式State

2 go语言实现

2.1 实现Current

type Work struct {
	hour    int
	current State
	finish  bool
}

func (w *Work) SetState(s State) {
	w.current = s
}

func (w *Work) SetHour(hour int) {
	w.hour = hour
}

func (w *Work) SetFinishState(finish bool) {
	w.finish = finish
}

func (w Work) WriteProgram() {
	w.current.WriteProgram(w)
}

2.2 实现State与ConcreteState

type State interface {
	WriteProgram(work Work)
}

type ForenoonState struct{}

func (fs ForenoonState) WriteProgram(work Work) {
	if work.hour < 12 {
		fmt.Println("上午")
	} else {
		work.SetState(NoonState{})
		work.WriteProgram()
	}
}

type NoonState struct{}

func (ns NoonState) WriteProgram(work Work) {
	if work.hour < 13 {
		fmt.Println("中午")
	} else {
		work.SetState(AfternoonState{})
		work.WriteProgram()
	}
}

type AfternoonState struct{}

func (as AfternoonState) WriteProgram(work Work) {
	if work.hour < 17 {
		fmt.Println("下午")
	} else {
		work.SetState(EveningState{})
		work.WriteProgram()
	}
}

type EveningState struct{}

func (es EveningState) WriteProgram(work Work) {
	if work.finish {
		work.SetState(RestState{})
		work.WriteProgram()
	} else {
		if work.hour < 21 {
			fmt.Println("晚间")
		} else {
			work.SetState(SleepingState{})
			work.WriteProgram()
		}
	}
}

type SleepingState struct{}

func (ss SleepingState) WriteProgram(work Work) {
	fmt.Println("睡着了")
}

type RestState struct{}

func (rs RestState) WriteProgram(work Work) {
	fmt.Println("下班回家")
}

2.3 客户端调用

func main() {
	tWork := state.Work{}
	tState := state.ForenoonState{}
	tWork.SetState(tState)
	tWork.SetFinishState(true)
	tWork.SetHour(22)
	tWork.WriteProgram()
}