应用领域

除了刚刚介绍的数学模型应用,有限状态机在许多不同领域都有重要应用,包括电气工程、语言学、计算机科学、哲学、生物学、数学和逻辑学。有限状态机归属于自动机理论,下面的自动机理论的领域分层图中就可以看出,越是外层的概念越复杂。

有限状态机的举例

我们就拿身边最经典的电风扇来举例。假如电风扇有4个按钮,分别是关、1档、2档和3档,关按钮负责关闭电风扇,也就是停止电风扇的转动;而1、2、3档都可以让电风扇开启,且风扇转动的速度不一样,产生的风力也不一样。

这时我们判断出风扇的4个状态,分别是关闭(poweroff)、1档(1st gear)、2档(2nd gear)、3档(3rd gear)。而4个按钮的按下操作可以影响电风扇的状态。下面用状态图来说明:

如果看不清楚,还有状态转移表

为了更直观的让程序员了解FSM具体有什么用,我将电风扇的有限状态机用程序来演示。

Go语言下的有限状态机

一共2个文件,fsm.go是有限状态机的抽象定义,main.go里是有限状态机在电风扇上的具体状态呈现,代码如下:

// fsm.gopackage mainimport ( "fmt" "sync")type FSMState string // 状态type FSMEvent string // 事件type FSMHandler func() FSMState // 处理方法,并返回新的状态// 有限状态机type FSM struct { mu sync.Mutex // 排他锁 state FSMState // 当前状态 handlers map[FSMState]map[FSMEvent]FSMHandler // 处理地图集,每一个状态都可以出发有限个事件,执行有限个处理}// 获取当前状态func (f *FSM) getState() FSMState { return f.state}// 设置当前状态func (f *FSM) setState(newState FSMState) { f.state = newState}// 某状态添加事件处理方法func (f *FSM) AddHandler(state FSMState, event FSMEvent, handler FSMHandler) *FSM { if _, ok := f.handlers[state]; !ok { f.handlers[state] = make(map[FSMEvent]FSMHandler) } if _, ok := f.handlers[state][event]; ok { fmt.Printf("[警告] 状态(%s)事件(%s)已定义过", state, event) } f.handlers[state][event] = handler return f}// 事件处理func (f *FSM) Call(event FSMEvent) FSMState { f.mu.Lock() defer f.mu.Unlock() events := f.handlers[f.getState()] if events == nil { return f.getState() } if fn, ok := events[event]; ok { oldState := f.getState() f.setState(fn()) newState := f.getState() fmt.Println("状态从 [", oldState, "] 变成 [", newState, "]") } return f.getState()}// 实例化FSMfunc NewFSM(initState FSMState) *FSM { return &FSM{ state: initState, handlers: make(map[FSMState]map[FSMEvent]FSMHandler), }} // main.gopackage mainimport ( "fmt")var ( Poweroff = FSMState("关闭") FirstGear = FSMState("1档") SecondGear = FSMState("2档") ThirdGear = FSMState("3档") PowerOffEvent = FSMEvent("按下关闭按钮") FirstGearEvent = FSMEvent("按下1档按钮") SecondGearEvent = FSMEvent("按下2档按钮") ThirdGearEvent = FSMEvent("按下3档按钮") PowerOffHandler = FSMHandler(func() FSMState { fmt.Println("电风扇已关闭") return Poweroff }) FirstGearHandler = FSMHandler(func() FSMState { fmt.Println("电风扇开启1档,微风徐来!") return FirstGear }) SecondGearHandler = FSMHandler(func() FSMState { fmt.Println("电风扇开启2档,凉飕飕!") return SecondGear }) ThirdGearHandler = FSMHandler(func() FSMState { fmt.Println("电风扇开启3档,发型被吹乱了!") return ThirdGear }))// 电风扇type ElectricFan struct { *FSM}// 实例化电风扇func NewElectricFan(initState FSMState) *ElectricFan { return &ElectricFan{ FSM: NewFSM(initState), }}// 入口函数func main() { efan := NewElectricFan(Poweroff) // 初始状态是关闭的 // 关闭状态 efan.AddHandler(Poweroff, PowerOffEvent, PowerOffHandler) efan.AddHandler(Poweroff, FirstGearEvent, FirstGearHandler) efan.AddHandler(Poweroff, SecondGearEvent, SecondGearHandler) efan.AddHandler(Poweroff, ThirdGearEvent, ThirdGearHandler) // 1档状态 efan.AddHandler(FirstGear, PowerOffEvent, PowerOffHandler) efan.AddHandler(FirstGear, FirstGearEvent, FirstGearHandler) efan.AddHandler(FirstGear, SecondGearEvent, SecondGearHandler) efan.AddHandler(FirstGear, ThirdGearEvent, ThirdGearHandler) // 2档状态 efan.AddHandler(SecondGear, PowerOffEvent, PowerOffHandler) efan.AddHandler(SecondGear, FirstGearEvent, FirstGearHandler) efan.AddHandler(SecondGear, SecondGearEvent, SecondGearHandler) efan.AddHandler(SecondGear, ThirdGearEvent, ThirdGearHandler) // 3档状态 efan.AddHandler(ThirdGear, PowerOffEvent, PowerOffHandler) efan.AddHandler(ThirdGear, FirstGearEvent, FirstGearHandler) efan.AddHandler(ThirdGear, SecondGearEvent, SecondGearHandler) efan.AddHandler(ThirdGear, ThirdGearEvent, ThirdGearHandler) // 开始测试状态变化 efan.Call(ThirdGearEvent) // 按下3档按钮 efan.Call(FirstGearEvent) // 按下1档按钮 efan.Call(PowerOffEvent) // 按下关闭按钮 efan.Call(SecondGearEvent) // 按下2档按钮 efan.Call(PowerOffEvent) // 按下关闭按钮}

执行后返回: