11

10

[状態マシン図] 履歴状態を考える

2013.11.10(23:15)

履歴状態も状態マシン図を描くうえで大切な要素なので、ここで一度しっかり考えておこう。

history0.png

待機中と印刷中、およびエラー発生中の3つの状態がある。
待機中からエラーが発生して解消したら待機中に戻り、
印刷中からエラーが発生して解消したら印刷中に戻る
このような状態マシンを考えてみよう。(ここで問題を解いてください)

history1.png

これが普通の解答。エラーなし状態の中で、開始疑似状態からの遷移に履歴コネクタがついている。初めてこの状態に入ったときは待機中に遷移する。2回目以降にこの状態に入ってくるときは、前回この状態を脱出したときにいた状態と同じ状態に戻る。

(この図には、開始疑似状態から出て履歴コネクタにつながるヌル遷移に、アクションが設定されていないが、もしアクションが設定されていた場合は、初めてこの状態に入ったときだけそのアクションが実行され、2回目以降にこの状態に入ってくるときはそのアクションは実行されない)

さて、この履歴コネクタがある状態マシンを、履歴コネクタを使わずに描いてみよう。(ここで問題を解いてください)

history2.png

完全に同じではないがだいたい同じ動きをする。図中、GEN(イベント名)はイベントを発生させて自分自身に投入するマクロ、IS_IN(状態名)はその状態にいるときにtrueを返すマクロである。

直交状態の上側で、待機中と印刷中のときに、エラーが発生すると、エラーあり状態に遷移する。待機中と印刷中のときは、それぞれの状態に入ったところで、直交状態の下側に対してイベントを投げて、待機中にいるのか印刷中にいるのかをラッチして覚えておく。(ブルースダグラスのLatch Stateパターン)

やがてエラーが解消して、エラーなし状態に戻るときに、ラッチしておいた状態のどちらだったかによって戻り先を待機中または、印刷中に切り替える。

直交状態の下側は、待機中にいるのか印刷中にいるのかをラッチしておくだけで、待機中から印刷中に遷移することなどは表現していないことに注意。それは上側で表現されているのでそれで十分である。直交状態の下側は、いつ、なにが発生しても、発生したことを覚えることに集中する。(ブルースダグラスのAny Stateパターン)

イベントを生成して状態マシンに投入することは実際にはコストがかかるので、このような冗長な設計にはしないが、このような情報が、そのようなタイミングで保存され、参照されていることは知っておいたほういいだろう。

状態マシン図ではUML2.0で既定されていること以外に、状態にイベントを投入することと、状態が指定された状態にいるのかboolで判断ことができる。前者はアクションで、後者はガード条件などで使うことができる。必要に応じてそれらも使って複雑な状態マシンを設計することになる。

このように履歴状態について考えてみると、履歴コネクタのほか、直交状態、Latch Stateパターン、Any Stateパターン、イベントを作って投入すること、どの状態にいるのか判定することなど、さまざまなことが学べる。

今回はふれなかったが、ここまでの知識を使って、UML2.0浅い履歴と深い履歴の違いを、浅い履歴コネクタと深い履歴コネクタを使わずに表現してみると面白い。(次の問題として解いてみてください)

参考文献
  1. リアルタイムUMLワークショップ (ブルース・ダグラス)
    http://www.amazon.co.jp/dp/4798121118/
    p.212 Any State パターン
    p.197 Latch State パターン
  2. UML2.0仕様書
    http://www.amazon.co.jp/dp/4274066630/
    p.695 深い履歴、浅い履歴、履歴コネクタ
プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示