仕事でチャットボットを作る可能性があり、セリフ管理にstate machineが使えるかもということで、golang で state machineを触ってみました。

state machine とは?

image.png

図のように、ある状態からある状態へ遷移するなどの構造を表したものです。
なので、現在のstate -> 遷移可能なstate -> 次のstateの情報をそれぞれのnodeが持つことになります。

尚正式名称は finite state machine と呼ぶ、 state machine は省略形のようです。

golangでのFSM

https://github.com/looplab/fsm
今回使ったライブラリは上のものです。

nodeの生成

const (
        start  = "start"
        middle = "middle"
        end    = "end"
        finish = ""
    )

    eventTree := fsm.Events{
        {
            Name: start,
            Src:  []string{start},
            Dst:  middle,
        },
        {
            Name: middle,
            Src:  []string{start},
            Dst:  end,
        },
        {
            Name: end,
            Src:  []string{end,start},
            Dst:  finish,
        },
        {
            Name: finish,
            Src:  []string{finish,middle},
            Dst:  finish,
        },
    }

このライブラリはEventという単位で遷移イベントを定義します。
それぞれ、


* Src : 遷移元のnode
* Dst : 遷移先のnode

となります。

state machine の生成

Eventを定義したら、state machineを生成します。
* 初期node名
* 全体のnodeの配列
* コールバック関数(特定のタイミング処理を実行できるもの、今回は省略)

    ownFsm := fsm.NewFSM(
        start,
        eventTree,
        fsm.Callbacks{},
    )

これでstate machineを生成できます。
あとは初期nodeから遷移可能なnodeを指定すると遷移できます。

ownFsm.Current() // start 
ownFsm.Event(start) // start eventが発火し、Dstのnodeへ遷移
ownFsm.Current() // middle

可視化

この構造を頭の中で毎回書くのは非常にしんどいです。
しかし、このライブラリは、state machine を可視化する機能がついています。

fsm.VisualizeWithType(ownFsm,fsm.GRAPHVIZ)

こんな形で、state machineと可視化方式を指定すると、

digraph fsm {
    "middle" -> "finish" [ label = "finish" ];
    "end" -> "finish" [ label = "end" ];
    "finish" -> "finish" [ label = "finish" ];
    "start" -> "finish" [ label = "end" ];
    "start" -> "end" [ label = "middle" ];
    "start" -> "middle" [ label = "start" ];

    "end";
    "finish";
    "middle";
    "start";
}

可視化のフォーマットに対応した、テキストを生成してくれます。
今回の場合は graphvizを指定したので、
http://www.webgraphviz.com/

上記で生成されたテキストを貼り付けて、generateすると可視化されます。

今回だとこんな感じ

スクリーンショット 2021-07-18 0.55.14.png

Eventは矢印の遷移の部分を指しています。

最後に

チャットボットで利用する際は、初期位置を変えたstate machineを毎回生成して、Eventを呼び出せばいけそうなのでは?と雑に考えてました。

それでは良いstate machine ライフを。

广告
将在 10 秒后关闭
bannerAds