【Go-设计模式】状态模式 详解

概念:
状态模式用于 分离 状态 和 行为
主要用来解决对象在 多种状态转换 时,需要对外输出 不同的行为 的问题
状态 和 行为 是一一对应的,状态之间 可以 相互转换
当一个对象的 内在状态 改变时,允许 改变其行为

UML:

- Context:
环境角色,用于 维护 State 实例,这个实例定义 当前状态 - State:
抽象状态角色,定义一个 接口封装 与 Context 的 一个 特点接口相关行为 - ConcreteState:
具体的状态角色,每个子类 实现 一个与 Context的 一个状态相关行为
示例:
环境对象:
type Context struct {
State State
}
func (this *Context) StartProcess() {
this.State.ShowState()
this.State.NextState(this)
}
func NewContext(initStateVal int64) Context {
return Context{
State: ConcreteState1{
Attr1: initStateVal,
},
}
}
抽象的状态 功能接口:
type State interface {
ShowState()
NextState(ctx *Context)
}
具体的 状态类:
具体的 状态类1:
type ConcreteState1 struct {
Attr1 int64
}
func (this ConcreteState1) ShowState() {
fmt.Println("当前状态为:", this.Attr1)
}
func (this ConcreteState1) NextState(ctx *Context) {
ctx.State = ConcreteState2{
Attr1: 2,
}
}
具体的 状态类2:
type ConcreteState2 struct {
Attr1 int64
}
func (this ConcreteState2) ShowState() {
fmt.Println("当前状态为:", this.Attr1)
}
func (this ConcreteState2) NextState(ctx *Context) {
ctx.State = ConcreteState3{
Attr1: 3,
}
}
具体的 状态类3:
type ConcreteState3 struct {
Attr1 int64
}
func (this ConcreteState3) ShowState() {
fmt.Println("当前状态为:", this.Attr1)
}
func (this ConcreteState3) NextState(ctx *Context) {
ctx.State = ConcreteState1{
Attr1: 1,
}
}
测试:
package main
import (
"DemoProject/design/base23/state" // 根据自己的项目路径定制
)
func main() {
// state
context := state.NewContext(1)
for i := 0; i < 5; i++ {
context.StartProcess()
}
}
注意事项:
优点:
-
代码有很强的 可读性
状态模式 将 每个状态的行为 封装到 对应的一个类中 -
方便维护
将 容易产生问题 的 if-else 语句 删除了,如果把 每个状态的行为 都放到 一个类 中,
如果 每次调用方法 时都要判断 当前是什么状态,不但会产出 很多 if-else 语句,而且容易出错 -
符合“开闭原则”
容易增删状态
缺点:
会产生很多类
每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护难度
应用场景:
当一个事件或者对象有 很多种状态,状态之间会 相互转换,对 不同的状态 要求有 不同的行为 的时候, 可以考虑使用 状态模式

浙公网安备 33010602011771号