安装好IDEA和GO插件,创建项目GoDemo
键入代码:
FSM.go
package src
import (
"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.Print("[警告] 状态(%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()
}
//实例化FSM
func NewFSM(initState FSMState) *FSM {
return &FSM{
state: initState,
handlers: make(map[FSMState]map[FSMEvent]FSMHandler),
}
}
FSM_demo.go
package main
import (
"fmt"
. "./src"
)
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);
efan.Call(FirstGearEvent);
efan.Call(PowerOffEvent);
efan.Call(SecondGearEvent);
efan.Call(PowerOffEvent);
}
运行结果:
D:\AI\IntelliJ-IDEA\bin\runnerw.exe D:\AI\Go\bin\go.exe run E:/各种语言/Go/projects/GoDemo/FSM_demo.go
电风扇开启3档,发型被吹乱了!
状态从 [ 关闭 ] 变成 [ 3档 ]
电风扇开启1档,微风徐来!
状态从 [ 3档 ] 变成 [ 1档 ]
电风扇已关闭
状态从 [ 1档 ] 变成 [ 关闭 ]
电风扇开启2档,凉飕飕!
状态从 [ 关闭 ] 变成 [ 2档 ]
电风扇已关闭
状态从 [ 2档 ] 变成 [ 关闭 ]