JavaScript / Node.js 開発に便利!! javascript-state-machine を使ってみました。
2015.12.26
この記事は最終更新日から1年以上が経過しています。
JavaScriptでstate管理できる「 javascript-state-machine」 を使ってみました。
ちょっとマニアックなライブラリになるかも知れませんが、JavaScript開発を行う方にはメジャーなのかもですね。
githubのstarも2500を超えていまして、明らかに私が公開した「MessageViewJS」よりも人気がありますね!w(当たり前か。)
近年、node.jsなどJavascriptの発展に伴い、フロントで行える処理も拡大しこの辺も考慮する事になってきて
需要が高まってきているかと思います。いやー大変w
github
javascript-state-machine
https://github.com/jakesgordon/javascript-state-machine
「 javascript-state-machine」 とは所謂UMLでいうところの図でその箇所を扱うにはとっておきのライブラリとなっております。
そもそもUMLってなんぞやという方に軽くご説明を
UMLはUnified Modeling Languageの略で、オブジェクト指向分析、
設計においてシステムをモデル化する際の記法(図法)を規定した統一モデリング言語(ビジュアル・ラン ゲージ)となります。
一般のWebサイトや、Webサービスではなかなか用いる機会もないかと思いますが、
大規模なシステム開発や、ゲームのような複雑な設計、仕様には必要不可欠となってきます。
と、図をみれば「あぁ。みたことある。」と言う方もいるかと思います。
よく見るのはこのような アクティビティ図(activity diagram)ではないでしょうか。
アクティビティ図(activity diagram)
アクティビティ図(activity diagram)は、業務や処理の流れを表すために、
関連する複数の業務手順や処理ステップを順序だてて配置したものとなります。
UMLの振る舞い図に分類されます。
JavaScriptのライブラリや、UI処理などでも使用されるのではないでしょうか。
こちらは私もよく書いてます。
クラス図(class diagram)
その他、オブジェクト指向で設計する場合などは、クラス図(class diagram)を利用するかと思います。
クラス図(class diagram)では、モデルの静的な構造を表す図で、問題領域やシステムの構造を表現できます
ECMAScript6では、TypeScriptやCoffeeScriptなどの所謂AltJSも用いる事もなく、
classが使えるようになりますので、JavaScriptを書かれる方は
必然的にこの部分は理解しておかないといけないでしょう。UMLの構造図に分類されます。
と、色々書いてきましたが、いよいよ本題の件となるのですが、
UMLでいう状態図(statechart diagram)が今回の件にあたります。
状態図(statechart diagram)
ひとつのオブジェクトの状態変化を表した図で、外部からの入力と、 それに対するオブジェクトの状態遷移を表します。
と、UMLに関してすごく噛み砕いて書いてきましたが、とりあえず触っていきます。
javascript-state-machine
github
javascript-state-machine
https://github.com/jakesgordon/javascript-state-machine
git clone
git clone https://github.com/jakesgordon/javascript-state-machine.git
git cloneを行うと、ディレクトリ直下にindex.htmlが存在するかと思いますので、
そちらをブラウザで開くとdemoを動かす事が出来ます。
このデモはDemo classで構成されていて、
Demo classには、「clear」「calm」「warm」「panic!」の4つのイベントがあり
「green」「yellow」「red」の3つの状態を持っています。
この状態遷移を行うのがjavascript-state-machineの役割となります。
早速、demoのソースを確認すると
var fsm = StateMachine.create({ 省略... events: [ { name: 'start', from: 'none', to: 'green' }, { name: 'warn', from: 'green', to: 'yellow' }, { name: 'panic', from: 'green', to: 'red' }, { name: 'panic', from: 'yellow', to: 'red' }, { name: 'calm', from: 'red', to: 'yellow' }, { name: 'clear', from: 'red', to: 'green' }, { name: 'clear', from: 'yellow', to: 'green' }, ],
eventの登録はこのようになっていて、それぞれ
{ name: イベント名, from: 状態遷移前, to: 状態遷移後 },
となっております。
ちなみにfsmは、有限オートマトン(FSM:Finite State Machine)となっております。
warnイベントは、greenのみでyellowへと状態遷移します。
panicイベントは、green、yellowからredへと状態遷移します。
calmイベントは、redのみで、yellowへと状態遷移します。
clearイベントは、red、yellowからgreenへと状態遷移します。
この様に、状態遷移を制限しているので、強制的にgreenからclearイベントを発火させようとしても、
Demo.clear();
エラーが出るのが確認できるかと思います。
現在の状態を取得するには「current」で参照できます。
fsm.current
また、状態遷移が行えるかの判定は「cannot」で行えます。
fsm.cannot('panic');
戻り値はbooleanで、行える場合は「false」出来ない場合は「true」となります。
Callbacks
その他、callbackが登録されているのが確認出来ます。
callbacks: { onbeforestart: function(event, from, to) { log("STARTING UP"); }, onstart: function(event, from, to) { log("READY"); }, onbeforewarn: function(event, from, to) { log("START EVENT: warn!", true); }, onbeforepanic: function(event, from, to) { log("START EVENT: panic!", true); }, onbeforecalm: function(event, from, to) { log("START EVENT: calm!", true); }, onbeforeclear: function(event, from, to) { log("START EVENT: clear!", true); }, ...省略 }
コールバックの4種類は、次の命名規則を使用して、ステートマシンにメソッドを取り付けることで使用できます。
・onbeforeEVENT- event 発火前
・onleaveSTATE- 遷移前の状態から離れる際
・onenterSTATE- 状態遷移後
・onafterEVENT- event 発火後
省略可
2つのcallbackは省略することも可能となっております。
・onEVENT- onafterEVENTの省略
・onSTATE- onenterSTATEの省略
例:
onpanic: function(event, from, to) { log("FINISH EVENT: panic!"); },
また、 4つの汎用のコールバックは、すべてのイベントと状態の変更をキャプチャするために使用することができます。
・onbeforeevent- 全てのevent発火前
・onleavestate- 全ての状態の遷移前
・onenterstate-全ての状態の遷移後
・onafterevent-全てのevent発火後
例:
onafterevent: function(event, from, to) { console.log('全てのevent 発火後にcallback'); },
callback 引数
すべてのコールバックは同じ引数が渡されます
・ event name
・ from state
・ to state
例:
onenterstate: function(event, from, to) { console.log(event, from, to); },
と、後は公式の説明を見ていただければと思います。
とりあえず、新しく黒を追加してみましょう。
黒を追加
eventsに新しく’dark’ eventを追加し、状態遷移で blackへと遷移できる様に以下の様に追加します。
events: [ 省略.. { name: 'clear', from: 'black', to: 'green' }, { name: 'dark', from: 'green', to: 'black' }, { name: 'dark', from: 'yellow', to: 'black' }, { name: 'dark', from: 'red', to: 'black' }, ]
HTMLの方から、darkイベントを発火できる様に追加。
<button id="dark" onclick="Demo.dark();">dark!</button>
クリックして、darkイベントを発火させると、この様な感じに
blackから clearイベントのみ起こせる様に登録しているので、押せるボタンも clearのみとなります。
clear押すと元どおり。
と、こんな感じで
javascript-state-machineについて書いてきました。
通常のwebサイトやwebサービスを作る上で、触れる機会も少ないかもしれませんが、
JavaScriptでの大規模なシステム開発や、ゲーム制作では必要となってくる要素で、
現在もHTML5によるゲーム制作なども再び盛り上がってきている感じもあって、
今後扱う機会が増えるのではないでしょうか。
ではではー。