1. 程式人生 > >go - FSM(有限狀態機)初體驗

go - FSM(有限狀態機)初體驗

層次 time lba 當前 時機 警告 pen nil 自定義

FSM有限狀態機

/**
* @Author: wsp
* @Time    : 2018/4/11 16:45
* @Description:
 */
package fsmStrudy

import (
    "fmt"
    "github.com/looplab/fsm"
)

type Door struct {
    To  string
    FSM *fsm.FSM
}

func NewDoor(to string) *Door {
    d := &Door{
        To: to,
    }

    d.FSM = fsm.NewFSM(
        
"closed", fsm.Events{ {Name: "open", Src: []string{"closed"}, Dst: "open"}, {Name: "close", Src: []string{"open"}, Dst: "closed"}, }, fsm.Callbacks{ "enter_state": func(e *fsm.Event) { d.enterState(e) }, }, ) return d } func (d
*Door) enterState(e *fsm.Event) { fmt.Printf("The door to %s is %s\n", d.To, e.Dst) } func FsmStudy() {
   // 創建door對象 door :
= NewDoor("heaven")    // 狀態改變,此時對應fsm.Events中的Name:open狀態,此時狀態由closed轉變為open
// 然後調用回調函數 d.enterState(e),打印出當時狀態 err :
= door.FSM.Event("open") if err != nil {
fmt.Println(err) } err = door.FSM.Event("close") if err != nil { fmt.Println(err) } }

然後進行深一層次,豐富狀態機轉變時對應回調函數的調用及執行,類似java中攔截器,狀態轉變之前執行對應before_xxx的函數,

執行完後執行leave_state的函數,代碼:

/**
* @Author: wsp
* @Time    : 2018/4/11 16:45
* @Description: 有限狀態機
 */
package fsmStrudy

import (
    "fmt"
    "github.com/looplab/fsm"
    "testing"
)

func TestFsmStudy(t *testing.T) {
    FsmStudy()
}

func TestFsmStudy2(t *testing.T) {
    //創建一個狀態機
    //三個參數:1.默認狀態 2.定義狀態事件 3.定義狀態轉變時調用的函數
    fsm := fsm.NewFSM(
        "green",
        fsm.Events{
            //狀態事件的名稱   該事件的起始狀態Src         該事件的結束狀態Dst
            //即:狀態事件warn(警告事件)表示事物的狀態從狀態green到狀態yellow
            {Name: "warn", Src: []string{"green"}, Dst: "yellow"},
            {Name: "panic", Src: []string{"yellow"}, Dst: "red"},
            {Name: "yellow", Src: []string{"red"}, Dst: "blue"},
            {Name: "calm", Src: []string{"red"}, Dst: "yellow"},
        },
        //狀態事件調用函數,在此稱為 時機函數。關鍵字用‘_‘隔開,格式是:"調用時機_事件或狀態"
        //before表示在該事件或狀態發生之前調用該函數,如"before_warn",表示在warn
        //這個狀態事件發生前調用這個函數。"before_yellow"表示進入yellow狀態之前調用
        //該函數。
        //依此類推,after表示在...之後,enter表示在進入...之時,leave表示在離開...
        //之時。
        fsm.Callbacks{
            //fsm內定義的狀態事件函數,關鍵字指定的是XXX_event和XXX_state
            //表示任一的狀態或狀態事件
            "before_event": func(e *fsm.Event) {
                fmt.Println("before_event")
            },
            "leave_state": func(e *fsm.Event) {
                fmt.Println("leave_state")
            },
            //根據自定義狀態或事件所定義的狀態事件函數
            "before_yellow": func(e *fsm.Event) {
                fmt.Println("before_yellow")
            },
            "before_warn": func(e *fsm.Event) {
                fmt.Println("before_warn")
            },
        },
    )
    //打印當前狀態,輸出是默認狀態green
    fmt.Println(fsm.Current())
    //觸發warn狀態事件,狀態將會從green轉變到yellow
    //同時觸發"before_warn"、"before_yellow"、"before_event"、"leave_state"函數
    fsm.Event("warn")
    fmt.Println("======================")
    fsm.Event("panic")
    fmt.Println("======================")
    fsm.Event("yellow")
    //打印當前狀態,輸出狀態是yellow
    fmt.Println(fsm.Current())
}

go - FSM(有限狀態機)初體驗