状態遷移表による設計手法について解説。第5回では、「状態遷移表からの実装」をテーマに、状態遷移表(設計書)から実装に落とし込むまでのプロセスとその方法について詳しく説明する。
組み込みソフトウェアが抱える一番の課題は「設計品質の向上」です。本連載の主役「状態遷移表」であれば、“イベント”と“状態”の全ての組み合わせを捉えることができるため、「モレ」「ヌケ」のない品質の良い設計が可能です。そして、不具合発生による手戻りコストの削減や開発効率の向上にも役立ちます。
こうした理由から、組み込みソフトウェア開発の世界では、長年、状態遷移系モデルで設計が行われています。
前回は、“状態遷移表を使用した設計モデル”をテーマに、拡張階層化状態遷移表を用いた設計手法を紹介しました。ソフトウェア開発とは、当然のことながら、設計書の作成がゴールではありません。最終的に、プログラミング(モデルからの自動コード生成を含む)を行い、ソフトウェアを完成させることがゴールです。つまり、設計書は、プログラミングを行う目的のために作成するものと言い換えることもできます。ということで、今回は、「状態遷移表からの実装」について解説します。
なお、本連載では以下の6つのテーマを順番にお届けしていきます。
今回のテーマ、状態遷移表からの実装の本題に入る前に、“プログラミングを行うための表現方法”について確認しておきましょう。
プログラミングの世界には、C、C++、Javaなど、さまざまな言語が存在します。これと同じように、プログラムの構造や処理の流れを表現するものとして、フローチャートや、PAD、HCPチャートといった構造化プログラミングを行うための構造化チャートなど、実に多くの表記手法があります。
今回は、最も基本的な手法であり、単純な表記で構成されるフローチャートを用いながら、解説を進めていきます。
フローチャート(Flow Chart)とは、“流れ図”または“流れ作業図”のことです。各工程(処理)を示す部品は“JIS X 0121:1986”により規格化されており、形・流れる方向などが統一化されています。端子からスタートし、処理の流れは、→で表現します。各処理は、□で表現し、選択、反復などの条件部分は、◇で表現します(図1)。
今回の目的は、状態遷移表からの実装プロセスを紹介することですが、その前に、“基本仕様から直接実装した場合”を想定したフローチャートを作成します。ここで作成したフローチャートは、後ほど、“状態遷移表から実装した場合”のフローチャートと比較します。
図2に、連載第3回「状態遷移表を使用した要求分析モデル」で掲載したキッチンタイマーの基本仕様を示します。
図2に示した基本仕様に従って、下記の手順で処理の流れをフローチャートで表現していきます。
(1)まず、「時間設定ボタン」が押された場合は、「カウントダウン時間設定」処理を行います。同時に、「スタートストップボタン」が押された場合は、「カウントダウン開始」処理を行います。これらのイベントをループで参照し続けます。
(2)カウントダウンが開始された後で、「カウントダウン終了」した場合は、「カウントダウン停止&アラーム音出力」処理を行います。また、カウントダウン中で、カウントダウンが終了する前に、「スタートストップボタン」が押された場合は、「カウントダウン一時停止」処理を行い、カウントダウン処理を開始する前の「スタートストップボタン」を待っている箇所に移動します。
(3)アラーム音出力後で、「スタートストップボタン」が押された場合は、「アラーム音停止」処理を行い、時間設定を行う最初の箇所に戻ります。
フローチャートの表現方法は人それぞれなので、「これが絶対!」と一概には言えませんが、参考までに、今回作成したフローチャートを図3に示します。
それでは、図3のフローチャートを分析していきましょう。図3のフローチャートは、状態に着目せずに、処理の流れのみに着目して作成したため、下記のような特徴があります。
図3のフローチャートでは、「スタートストップボタン」を、3箇所で参照しています。同じ処理を3箇所それぞれで行う構造は、“良い構造”とはいえません。同じイベントであれば、1箇所にまとめて表現する方が、品質やメンテナンス性も良くなります。そのため、「スタートストップボタン」を1箇所で参照する構造を検討するべきです。
また、マイナーループが3つ存在しています。マイナーループは、処理の流れに従って、各イベント待ちを行っていますが、そのイベント待ちを行っているマイナーループが複数存在しています。マイナーループが複数存在すると、イベントの追加や変更を行う際に、それぞれのマイナーループで追加・変更を検討しなければなりません。つまり、品質やメンテナンス性を低下させる要因となります。従って、マイナーループをできるだけ少なくする構造を検討するべきです。
さらに、図3のフローチャートは、下部のマイナーループから上部のマイナーループへと動作する必要があります。プログラムは上部から下部へと動作するため、“順序性”が明確な切り替えには適していますが、カウントダウン状態のループから時間設定状態のループへ戻る状態遷移のように、“下部から上部へと移動する構造”の実装には、状態のループを切り替えるためのフラグや変数などが必要になってしまいます。
以上のことから、下記のような検討課題が見えてきます。
ところで、図3にある3つのマイナーループが、状態遷移設計の“状態”と同じであることに気が付いた方はいますか? 一番上が時間設定状態の際にループする部分です。そして、次がカウントダウン状態の際にループする部分で、一番下がアラーム音出力状態の際にループする部分です。このことから、図3のフローチャートは、マイナーループを使用して状態を表現しており、“マイナーループの切り替えにより、状態を切り替える構造”といえます。
それでは、状態遷移表(図5)からフローチャートを作成する手法を紹介します。
図5の状態遷移表からフローチャートを作成する手法は、「イベントドリブン型(E型)」と「ステートドリブン型(S型)」の2種類があります。それぞれ、イベント主体で実装するか、状態(ステート)主体で実装するかを指定した型になります。
イベントドリブン型は、イベント主体で実装を行うため、先にどの「イベント」が入ったかを解析し、その後、現在の「状態(ステート)」を解析して、動作させる処理を確定する型です。これに対し、ステートドリブン型は、状態(ステート)主体で実装を行うため、先に現在の「状態(ステート)」を解析し、その後、どの「イベント」が入ったかを解析して、動作させる処理を確定する型です。イベントドリブン型とステートドリブン型の特徴については後ほど詳しく説明します。
Copyright © ITmedia, Inc. All Rights Reserved.