
状態(ステータス)遷移を使ったプログラムはあまり見かけませんが、開発業務で見かけるプログラムで、「状態遷移を使えばもっと良くなるのに」と思うことが時々あります。
最近は状態遷移そのものを知らないか、知っていても使い方を知らない開発者も多いので、非常にもったいないと感じています。
そこで、今回は状態遷移を使ったプログラムについて説明したいと思います。
一般的な状態遷移の設計は以下のような状態遷移図で行うとされていますが、もう、すでにわかりにくいですよね。
「どうやって書くの?」、「どうやって使うの?」って思ってしまいます。

この図が、状態遷移が使われない原因じゃないかと思ってしまいます。
単純な状態遷移なら、こんな図は必要ないし、複雑な状態遷移だと蜘蛛の巣みたいになっちゃうから使えないんです。
他にも
- 実際にどういったプログラムになるのか想像できない
- プログラムの仕様変更を表現できない
とかキリがないですね。
というわけで、今回は状態遷移を使ったシステムの構築についてご紹介したいと思います。
状態遷移図についても、もう少し使いやすいものを紹介したいとおみます。
が、その前に、そもそも、状態遷移の何がいいのかを説明しましょう。
一般的なシステムの構築例
状態遷移は常駐型プログラムで利用することが多いです。
制御プログラム、サービス、リスナー、ドライバー、常駐バッチなと。
常駐プログラム以外でワークフロー(承認処理)エンジンにも使ったことがあります。
今回は、例として以下のような「注文受付システム」を使ってみようと思います。

システム構成
例えば、製造依頼データを作成するバッチ(もしくは画面)処理を考えてみましょう。
製造依頼が必要なデータ以下のような条件となります。
- 受注データがある
- 在庫データがない
- 商品が社内製造品である
- 製造依頼データがない
製造依頼処理は、毎回、このようなデータ取得を行う必要があります。
こういった処理をシステムの各所、各プログラムに実装する必要があります。

システム改修
では、ここで「社外製造品を社内でも製造する」(商品区分に「内外製造品」を追加)という業務の変更に伴う仕様変更が発生した場合を考えてみましょう。
先ほどの製造依頼処理は以下のような変更が必要です。
- 受注データがある
- 在庫データがない
- 商品が社内製造品の場合
- 製造依頼データがない
- 商品が内外製造品の場合
- 製造ラインに空きがある
- 製造依頼データがない
同様に、各所のプログラムも変更が必要です。
実際にシステムの改修を行う場合は以下のように各所に修正を加えることになります。
社内で製造するかどうかの判断をどこで行うかということもシステム設計を行う上で重要な要素ですが、今回は製造依頼処理で行うこととしました。
そのため、社内で製造するか発注するかのフラグを製造依頼データで持つこととなり、結果的に発注処理が製造依頼データを確認する処理となります。
(いかにも、後付け付け焼刃対応です)

トラブル発生
ここで、「発注が行われない」というトラブルが発生したとします。
システム担当者は以下のように各データの状態を確認することになります。
- 対象商品は社外製造品か内外製造品か
- 内外製造品の場合、製造依頼データの外部フラグがONになっているか
- 社外製造品の場合、発注データは存在するか
このように、ひとつのトラブルの調査を行う時に複数のデータを確認して総合的に判断する必要があります。
データ構造が複雑であればあるほど調査に時間がかかり、システム停止による被害は大きくなり、システム担当者の負担は増大します。
ステータス遷移を使ったシステム構築の例
では、上記の例をステータス遷移を使った場合を見ていきましょう。
システム構成
まず、改修前のシステムは以下のようになります。
非常にシンプルですが、大半の処理が抜けているように見えますね。
実は、ほとんどの処理が状態遷移エンジンの中に含まれてしまっているのでこのような構造となっています。

状態遷移エンジンの処理についてはステータス遷移図を使って表現します。
独自フォーマットを使用したステータス遷移図は以下の通りです。

処理のステップごとにステータスが分かれていることが分かると思います。
一見、複雑になってしまったようにも見えますし、こんなに分ける必要があるのか疑問に思われると思います。
こうすることでシステム改修によるプログラム変更の影響範囲を小さくすることができたり、トラブル対応を迅速に行うことができるようになります。
実際に使ってみるとシステム全体の処理の流れが理解しやすくなり、ステータスコードが共通言語となるためコミュニケーションも取りやすくなります。
システム改修
では、先ほどの例で見たシステム改修を行ってみましょう。
今回の改修ではステータス遷移(状態遷移エンジン)以外の改修は不要です。
ステータス遷移図の変更箇所は以下の通りです。

改修後のステータス遷移図は以下のようになります。

修正内容が明確で処理の流れの変化もわかりやすいですね。
既存のプログラムの改修はほとんど行わず、モジュールを追加することで対応できるためテストなどの改修コストも低く、リスクも少なく済みます。
(こういったメリットが分かると使わないのがもったいないと思ってしまうんですよねぇ。)
トラブル発生
では、トラブル対応方法も見てみましょう。
といっても、非常にシンプルです。
先ほどの例のトラブルは「発注が行われない」というものでしたので、暫定的に対応するのであれば以下のデータ修正で完了です。
状態ステータステーブルの対象レコードのステータスコードを「205:内外製造判定待ち」を「300:発注データ処理待ち」に変更
ステータスコードを見れば、どの処理で問題が発生しているかもすぐに突き止められるので、各テーブルの状態を確認する必要もありません。
原因の特定と暫定対応が劇的に早くなります。
まとめ
今回はステータス遷移(状態遷移)を使ったシステム構築の魅力について紹介しました。
もちろん使い方こなすには経験が必要です。
ステータス遷移図を紹介しましたが、「そもそも、どこで区切ったらいいの?」となると思います。
このあたりが、私の先輩に「まだまだ」といわれるところですが、意外と素人考えで作っても大きな問題は発生しません。
一つ一つの処理がシンプルな処理になるように設計できていればおおよそ大丈夫です。
一度設計して全体的に眺めて、ごちゃごちゃしているところを再検討するという感じで設計してもらえればいいと思います。
システムの根幹にかかわる設計になることが多いので「ちょっと使ってみようか」という軽い感じにならないかもしれませんが、運用や保守に大きな恩恵をもたらすと思いますので、チャンスがあればぜひ使ってみてください。