LoginSignup
4

More than 1 year has passed since last update.

golangで始めるstate machine

Posted at

仕事でチャットボットを作る可能性があり、セリフ管理に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すると可視化されます。

今回だとこんな感じ

  • Name : イベントスクリーンショット 2021-07-18 0.55.14.png

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

最後に

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

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4