複雑さの調整:状態機械モデリングにおける順次的 vs. 同時的サブステートの紹介
紹介
現代のソフトウェアシステムが規模と機能を拡大するにつれて、フラットな状態図はすぐに扱いにくくなります。現実世界のアプリケーションは単純な線形動作をとる場合がほとんどではなく、相互に依存するワークフロー、バックグラウンド処理、ユーザー主導のインタラクションを管理する必要があります。これら複雑さに対処するために、状態機械モデリングは複合状態、単一の親状態内に内部動作をカプセル化するものです。これらの内部動作をどのように構造化するかというアーキテクチャ上の決定は、2つの基本的なパラダイムにかかっています:順次的(または)サブステートおよび同時的(かつ)サブステート.
これらのパラダイムの選択は、単なる図示上の好みではなく、システムアーキテクチャ、並行処理の扱い、エラー回復、保守性に直接影響します。このケーススタディでは、現代のeコマース注文ライフサイクル内で、両アプローチの実用的応用を検討し、順次的および同時的サブステートを活用して、耐障害性があり、スケーラブルで論理的に整合性のある状態機械を構築する方法を示します。

基礎的な概念
ケーススタディに取り組む前に、2つのサブステートアーキテクチャの理論的な違いを明確にすることが不可欠です。
順次的サブステート(または状態)
順次的構成では、複合状態は同時に1つのサブステートしか占有できません。遷移は、各状態が次の状態の開始前に完了しなければならない、予め定められた線形経路に従います。
-
論理条件: 状態A または 状態B。
-
最も適した用途: ステップバイステップのワークフロー、ウィザード、検証パイプライン、相互に排他的な運用モード。
同時的サブステート(かつ状態)
同時的構成では、複合状態は複数の独立した領域に分割されます。親状態がアクティブになると、すべての領域が同時に活性化されます、それぞれが独自のライフサイクルと状態遷移を維持します。
-
論理条件: 領域1(状態A) かつ 領域2(状態X)。
-
最も適した用途:並列プロセス実行、UI操作と並行して行われるバックグラウンド監視、および独立したサブシステム間の調整。
構造的比較
| 機能 | 順次サブステート | 並行サブステート |
|---|---|---|
| アクティブなステート | 任意の時点で正確に1つのサブステートがアクティブである。 | 1つのサブステートが すべての並列領域において同時にアクティブである。 |
| 内部変数 | 共有コンテキストで、順次変更される。 | 多くの場合、独立している。変更はスレッドセーフであるか、イベント駆動でなければならない。 |
| 複雑さ | 低~中程度。線形に追跡しやすい。 | 高い。同期の追跡と潜在的なレースコンディションの管理が必要。 |
| 終了条件 | 内部の最終ステートに到達する、または明示的な外部遷移を行う。 | 通常は すべての領域がすべて最終ステートに到達する(結合)するか、外部の中断を必要とする。 |
事例研究:EC注文ライフサイクル
これらの概念を実際の場面で説明するために、ECプラットフォームの注文処理パイプラインの2つの重要な段階をモデル化する。支払い処理 および 注文の履行。各段階は、特定のサブステートアーキテクチャが最適な選択である理由を示している。
段階1:支払い処理における順次サブステート
支払い処理は本質的に線形であり、ステートに依存している。承認は不正検証の前に、不正検証は資金の確保の前に実行されなければならない。ステップをスキップしたり、並行して実行したりすると、金融規制に違反し、取引の整合性が損なわれるリスクがある。したがって、順次(Or)構成は必須である。
@startuml
skinparam architecture {
BackgroundColor White
ArrowColor #222222
BorderColor #222222
}
title 順次的サブステート - 支払い処理
state PaymentProcessing {
[*] --> Idle
Idle --> Authorizing : ユーザーが支払いを送信
Authorizing --> Authorized : カード検証成功
Authorized --> Capturing : 決済をトリガー
Capturing --> Completed : 資金が確保された
state Authorizing : entry/ フェイク検出メトリクスのチェック
state Capturing : entry/ 仮払い口座から資金を移動
}
Completed --> [*]
@endum
アーキテクチャ上の教訓: 順次モデルは厳密な順序を強制する。エントリ/エグジットアクション(例:不正検出チェック、仮払い口座への資金移動)は予測可能なタイミングで発動されるため、デバッグ、監査ログ、ロールバック戦略が簡単になる。
フェーズ2:注文履行における並行サブステート
支払いが確保されると、システムは注文を出荷準備状態にしなければならない。しかし、物流準備と在庫管理は異なるデータストアを用い、異なるチームやサービスに関与しており、互いの完了に依存せずに進行できる。これらを順次的にモデル化すると、人工的なボトルネックが生じる。並行(And)構成により、両方のワークフローを並行して実行可能となり、注文処理全体の時間を劇的に短縮できる。
@startuml
title 並行サブステート - 注文履行
state OrderFulfillment {
' 物流領域
[*] --> PreparingPackage
note on link: **物流領域**
PreparingPackage --> GeneratingShippingLabel : 商品を箱詰め
GeneratingShippingLabel --> PackageReady : ラベルを印刷
--
' 在庫領域
[*] --> AllocatingStock
note on link: **在庫領域**
AllocatingStock --> UpdatingERP : 在庫を確認
UpdatingERP --> InventoryDeducted : ERP同期完了
}
OrderFulfillment --> Shipping : 両領域が完了した場合(結合)
@endum
アーキテクチャ上の教訓: 並行モデルは現実世界の並行性を反映している。各領域は独立して動作し、物流サービスがラベルを印刷している間に、在庫サービスがERPと同期できる。親ステートは、両領域が自然に完了した後のみ、出荷 に遷移する。これは暗黙の同期バリアとして機能する。
アーキテクチャ上の考慮事項とベストプラクティス
順次的と並行的サブステートの選択は、図面作成を越えた問題である。実行時の振る舞いやインフラ要件を決定する。
順次設計を優先すべき状況
-
ステート依存ルール: サブステートBが、サブステートAによってのみ生成されるデータ、トークン、または副作用に依存する場合、順次モデル化により決定論的な実行が保証される。
-
規制対象のワークフロー: コンプライアンス指向のプロセス(例:KYC検証、決済ゲートウェイ、多要素認証)は、監査可能な段階的な進行を必要とする。
-
ユーザー誘導型インターフェース: ユーザーが検証チェックポイントをスキップできない、マルチステップのウィザードや設定フロー。
並行設計を優先すべき状況
-
独立したサブシステム: 独立したサービスが異なるドメインを処理するアーキテクチャに理想的である(例:ハードウェアセンサーのポーリングがUIレンダリングと並行して実行される場合)。
-
パフォーマンス最適化: 並行サブステートは、非同期実行、ワーカーキュー、マイクロサービスの並行化といった機会を明確に示す。
-
継続的モニタリング: 主なビジネスロジックと並行して無期限に実行されるバックグラウンドプロセス(例:健全性チェック、ログ記録、テレメトリ)
同期の落とし穴を回避する(フォークとジョイン)
並行なサブステートは、アーキテクトが予見しなければならない特定のライフサイクルの課題をもたらす:
-
エントリ時の暗黙のフォーク: 親ステートに入ることで、実行フローがすべての領域に自動的に分割される。競合する状態設定を避けるために、初期化ロジックは慎重にスコープを定める必要がある。
-
エグジット時のジョイン: スムーズな終了は、通常すべての領域が最終状態に到達することを要する。領域が異なるタイミングで完了する場合、システムは無期限にブロッキングせずに完了状態を追跡しなければならない。
-
中断処理: 並行ステートからの強制的な退出を引き起こす外部遷移は、すべての並行領域を突然終了する、進行状況にかかわらず。予期せぬ終了が発生した場合にデータ破損を防ぐために、アーキテクトは補償トランザクション、クリーンアップフック、または冪等操作を実装しなければならない。
結論
ステートマシンモデリングは、システムの複雑性を管理するための強力な抽象化を提供するが、その効果は複合ステートを正しく構造化することにかかっている。順次サブステートは、決定論的で段階的な進行を強制する点で優れており、コンプライアンスが重視され、状態に依存するワークフローにおいて不可欠である。一方、並行サブステートは真の並列性を解放し、人工的なボトルネックなしに独立したサブシステムが同時に動作できるようにする。
eコマースの事例研究は、どちらのアプローチも普遍的に優れているわけではないことを示している。むしろ、これらはアーキテクトのツールキットにおける補完的なツールである。ビジネス要件を適切なサブステートアーキテクチャに丁寧にマッピングすることで、機能的に正しいだけでなく、パフォーマンスが高く、保守性が高く、障害に強いシステムを構築できる。現代のアプリケーションが非同期的でイベント駆動的、分散型のアーキテクチャをますます採用し続ける中で、OrステートとAndステートの違いを習得することは、堅牢でスケーラブルなソフトウェアシステムを設計するための基盤的なスキルとして、今後も重要である。














