仕事でチャットボットを作る可能性があり、セリフ管理にstate machineが使えるかもということで、golang で state machineを触ってみました。
state machine とは?
図のように、ある状態からある状態へ遷移するなどの構造を表したものです。
なので、現在の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すると可視化されます。
今回だとこんな感じ
Eventは矢印の遷移の部分を指しています。
最後に
チャットボットで利用する際は、初期位置を変えたstate machineを毎回生成して、Eventを呼び出せばいけそうなのでは?と雑に考えてました。
それでは良いstate machine ライフを。