golang 状态模式 状态机

566 阅读2分钟

什么是状态机

有限状态机FSM火简称状态机,是一种计算的数学模型。它是一个抽象的机器,再任何时间都可以处于有限的状态之一。FSM可以根据一些输入从一个状态转变为另一个状态;从一个状态到另一个状态的变化称为转换。

一个FSM由三个关键要素组成:初始状态、所有可能的状态列表、出发状态转换的输入

状态模式是一种对象行为型模式,其主要优点如下。
  1. 结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,满足“单一职责原则”。
  2. 将状态转换显示化,减少对象间的相互依赖。
  3. 状态类职责明确,有利于程序的扩展。
状态模式的主要缺点如下。
  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
  3. 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。

接下来,我们以一个程序来说明,一个工程生产一件产品,需要经过 需求调研,设计,开发,测试。


package main

import (
   "fmt"
)
//用全局变量定义一个产品,产品有很多状态
var Produce = Cp
//产品的状态
const (
   Cp uint32 = iota
   Sj
   Sc
   Cs
   End
)

type FlagChangeFunc func()
//定义map,产品进来,查询有无这个flag,有就去处理,没有就处理不了
var FlagTransitionTable = map[uint32]FlagChangeFunc{
   Cp: CpP,
   Sj: SjP,
   Sc: Scp,
   Cs: CsP,
}

func CpP() {
   fmt.Println("产品需求处理")
   Produce = Sj
}
func SjP() {
   fmt.Println("产品设计处理")
   Produce = Sc
}
func Scp() {
   fmt.Println("产品生产")
   Produce = Cs
}
func CsP() {
   fmt.Println("产品测试")
   Produce = End
}
//执行,先查询有没有,然后再去处理
func Execute(flag uint32) {
   if f := FlagTransitionTable[flag]; f == nil {
      fmt.Println("没有部门去处理")
   } else {
      fmt.Println("部门正在去处理")
      s := FlagTransitionTable[flag]
      s()
   }
}
func main() {
   for Produce != End {
      Execute(Produce)
   }

   fmt.Println("产品完成")

}

结果:这样,代码是不是非常清晰,结构清除

图片.png