一共 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
- 张大千擅长:下列哪一位著名画家擅长画虎A、张
- 中通400客服电话
- 怎么换身份证上的照片
- 专硕和学硕代码
- 中国法律还有死刑吗
- 在六点半用英语怎么说
- 主任医师是什么级别
- 知困下一句:人心齐泰山移人心散请问下一句是什么
- 怎么缩小电脑桌面图标
- 专业技术岗位:事业单位管理岗位如何转专业技术岗位
- 天龙八部中逍遥派
- 苹果平板忘记id及密码怎么办
- 可可以加什么偏旁
- 什么夺目成语四字词语
- 蛋挞底皮酥脆的诀窍
- 中国联通电话号码客服电话是
- 星星还是那颗星星歌曲
- 顺丰有单号查不到物流
- iphone设置短信中心号码失败
- oppo自动开关机在哪里设置
- 灭楚之战有多惨
- 迂回什么折成语
- 案件到法院多久能开庭
- 武汉人流俱佳都巿
- 春雨绵绵的意思
- b的大写字母怎么写
- 物什么什么什么成语
- 现任国家副主席都有谁
- 打印表格怎么铺满a4纸
- 一什么玻璃填量词