このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

web帳

記事詳細

2015.12.26

JavaScript / Node.js 開発に便利!! javascript-state-machine を使ってみました。

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)

2_04

アクティビティ図(activity diagram)は、業務や処理の流れを表すために、

関連する複数の業務手順や処理ステップを順序だてて配置したものとなります。

UMLの振る舞い図に分類されます。

JavaScriptのライブラリや、UI処理などでも使用されるのではないでしょうか。

こちらは私もよく書いてます。

クラス図(class diagram)

その他、オブジェクト指向で設計する場合などは、クラス図(class diagram)を利用するかと思います。

Class

クラス図(class diagram)では、モデルの静的な構造を表す図で、問題領域やシステムの構造を表現できます

ECMAScript6では、TypeScriptやCoffeeScriptなどの所謂AltJSも用いる事もなく、

classが使えるようになりますので、JavaScriptを書かれる方は

必然的にこの部分は理解しておかないといけないでしょう。UMLの構造図に分類されます。

と、色々書いてきましたが、いよいよ本題の件となるのですが、

UMLでいう状態図(statechart diagram)が今回の件にあたります。

状態図(statechart diagram)

Statemachine2

ひとつのオブジェクトの状態変化を表した図で、外部からの入力と、 それに対するオブジェクトの状態遷移を表します。

と、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を動かす事が出来ます。

スクリーンショット 2015-12-26 19.32.21

このデモは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();

スクリーンショット 2015-12-26 19.46.07

エラーが出るのが確認できるかと思います。

現在の状態を取得するには「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イベントを発火させると、この様な感じに

スクリーンショット 2015-12-26 21.00.46

blackから clearイベントのみ起こせる様に登録しているので、押せるボタンも clearのみとなります。
clear押すと元どおり。

スクリーンショット 2015-12-26 21.01.04
と、こんな感じで
javascript-state-machineについて書いてきました。
通常のwebサイトやwebサービスを作る上で、触れる機会も少ないかもしれませんが、
JavaScriptでの大規模なシステム開発や、ゲーム制作では必要となってくる要素で、
現在もHTML5によるゲーム制作なども再び盛り上がってきている感じもあって、
今後扱う機会が増えるのではないでしょうか。
ではではー。

  • RSSを登録する

  • follow us in feedly

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、港区六本木で活動中。

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。