有限状态机 FSM 的原理与 GO 的实现

Lucy 坐标: 99471 目录:婚姻家庭

一共 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 ) // 按下关闭按钮 }

执行后返回:

电风扇开启 3 档,发型被吹乱了!状态从 [ 关闭 ] 变成 [ 3 档 ] 电风扇开启 1 档,微风徐来!状态从 [ 3 档 ] 变成 [ 1 档 ] 电风扇已关闭状态从 [ 1 档 ] 变成 [ 关闭 ] 电风扇开启 2 档,凉飕飕!状态从 [ 关闭 ] 变成 [ 2 档 ] 电风扇已关闭状态从 [ 2 档 ] 变成 [ 关闭 ]

作者:陈康 stozen

链接:http://www.jianshu.com/p/37281543f506

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

微信扫一扫

订阅每日移动开发及 APP 推广热点资讯

公众号:CocoaChina

专题栏目
最新