Go入门学习实例——有限状态机

安装好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档 ] 变成 [ 关闭 ]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章