- 複雑なシステムの振る舞いを視覚的に構造化する形式で、基本的な state machine を拡張し、state explosion 問題に対処できるよう強化されている
- 振る舞いとコンポーネントの分離が可能になり、動作変更やコードの推論がしやすくなり、コンポーネントから独立したテストや例外的な状況の探索にも適している
- statechart を作る過程で、あり得る状態をすべて探索することになり、statechart ベースのコードは従来のコードより バグ数が少なかったという研究結果 もある
- SCXML 標準と各種言語のツール・ライブラリにより、モデルを読み、書き、実行でき、entry/exit action のような動作順序を正しく処理するのに役立つ
- 実行可能な machine format を使えば、1つの定義を single source of truth として実行時の動作と図を同時に保てるため、実装と設計の同期維持が重要になる
Statecharts 概要
- Statechart は複雑なシステムを扱うための視覚的な形式で、基本的な state machine を拡張したもの
- state machine が大きくなるほど生じる state explosion 問題に対処できるよう強化されている
- 振る舞いを図で表現できるが、ソフトウェアエンジニアリングでは可視化そのものより 振る舞いのモデリング と構造化に近い
- 関連する基礎説明は What is a state machine?, What is a statechart? に続く
Statecharts を使う理由
- 理解しやすい構造を持ち、多くの他のコード形式より把握しやすい
- 振る舞いとコンポーネントの分離が可能
- 動作変更がより容易になる
- コードの推論がよりしやすくなる
- コンポーネントと独立して振る舞いをテストできる
- statechart を作る過程で 可能な状態をすべて探索することになる
- statechart ベースのコードは従来のコードより バグ数が少なかったという研究結果 がある
- 見落としやすい 例外的な状況 を扱うのに適している
- 複雑性が増すほど 拡張性 が高い
- 開発者でない人にも理解しやすく、QA は 探索ツール として活用できる
- すでに多くのコードが暗黙的に state machine を含んでおり、statechart はそれを 明示的に表す方法 として機能する
Statecharts の負担と反対要因
- 新たな学習コストが必要
- 基盤概念である state machine 自体は多くのプログラマーにとって馴染みがあるかもしれない
- 既存のコーディング手法とかなり異なるため、見慣れないパラダイムに感じられることがある
- 小さな statechart では、動作を分離する過程によって コード行数が増えることがある
- 広く使われていない理由としては、認知不足と YAGNI がともに作用している
- よくある反対論としては、そこまで必要ではないこと、特定の技術トレンドに合わないこと、ライブラリ数が増えることが挙げられる
- Web アプリケーションではロード時間が長くなる可能性がある
- こうした長所と短所を合わせて見ても、導入効果は全体として 純利益 に近い
使用方法と SCXML
- SCXML は 2005年から2015年まで W3C で標準化された形式で、statechart のさまざまな意味規則と エッジケース処理 を定義している
- 複数の言語で SCXML を読み、書き、実行するツールがある
- 同じ モデル を保ちながら、構文だけが異なる派生形式もある
- さまざまなプラットフォーム向けの statechart ライブラリがあり、SCXML の意味規則をそれぞれ異なるレベルでサポートしている
- こうしたライブラリを使うと、entry/exit action のような動作順序を正しく処理するのに役立つ
- 追加の利用ガイドは how to use statecharts に続く
実行可能な Statecharts
- ドキュメントとしてだけ statechart を使うのではなく、実行可能な machine format を設計とランタイムの両方で使える
- 1つの定義を single source of truth として、実際のランタイム動作と視覚的な図を同時に動かせる
- 図をコードに移し替える作業が不要になる
- 手作業で変換する際に生じるバグを減らせる
- 図と実装が常に 同期された状態 を維持する
- 図がより精密になる
- 一方で図はかなり複雑になることがある
- 実行可能な statechart のための フォーマットとツールの選択肢 は限られている
- statechart とコンポーネントの間で 型安全性 を強く保証するのは難しい
- コード内に statechart 定義があれば、その表現を使って視覚的な statechart を自動生成できる
- 定義が JSON や XML のような別ファイルにある場合はさらに単純になる
コミュニティと追加資料
1件のコメント
Hacker Newsの意見
statechartsが引き続き注目されているのを見るのはうれしい
JS/TS向けの状態機械・statechartsの作成/実行/可視化ライブラリ XState を作っており、https://github.com/statelyai/xstateで見られる
10年以上取り組んできて学んだ核心は、statechartsは単なる文書ではなく 実行可能な振る舞い として扱うときに最も価値が大きいという点だ
どこにでも使う必要はないが、「次に何が起こるのか?」が現在の状態とイベントの両方に依存する場合に特に強力だ
こうしたチャートは、「今この状態でこのイベントが来たら次の状態は何で、どんな効果が実行されるのか?」に答えてくれるオラクルのように使える
次のメジャーバージョンのXStateアルファもほぼ準備ができており、ergonomics、型安全性、composability、新しい visualizer/editor に重点を置いている
基本的なオープンソースの可視化ツールは https://sketch.stately.ai にある
形式的仕様の面では SCXML は読んでみる価値がある: https://www.w3.org/TR/scxml
David Harelの原論文も非常に価値が高い: https://www.weizmann.ac.il/math/harel/sites/math.harel/files/users/user50/Statecharts.pdf
Laraconでstate machinesとstatechartsについての考えを整理して発表した動画もある
https://www.youtube.com/watch?v=1A1xFtlDyzU
SCXML にかなり近づきつつ、特に実行可能コンテンツでXML要件をなくした、かなり成熟した実装だ
prior artセクションにはXStateも参考事例として挙がっている
lit.jsと一緒に、ページ幅に反応し、propsと内部状態が多いdrawer型ナビゲーションコンポーネントに適用したが、XStateなしでどれほどひどいことになっていたか想像もできない
次のバージョンも楽しみだし、本当にありがとう
自動 TS型推論 がかなり良くて、軽い状態機械ロジックが必要な場面で使いやすい
以前は frontend/UI ecosystem でstatechartsが少しずつ勢いを得ているように見えたのに、なぜかその流れが消えてしまったのが残念だ
UIインタラクションに状態機械、特にstatechartsのような状態機械の組み合わせを使うと、複雑なフローをはるかに推論しやすくなる
初めて触れるならIan Horrucksの「Constructing the user interface with statecharts」を強く勧める
1999年の本だが、実際にどう適用し、どう使うべきかを説明する入門書としてはいまでも最高クラスだ
https://archive.org/details/isbn_9780201342789/mode/2up
週間npmダウンロードは400万を超えており、RiveやLottieFilesのようなアニメーションツールも状態機械機能を強く打ち出している
LangGraphのようなAIツールも状態機械ベースの上に成り立っている
こうしたアプリやツールがstatechartsの潜在力を完全に引き出すにはまだ時間が必要だろうが、出だしは良い
https://github.com/derkork/godot-statecharts
入門書でよく抜け落ちるのが history pseudo-states だ
H、Hを使うと、外から見たstatechartは形式的には非決定的になる
よく「現在の状態は入力の純粋関数だ」と説明されるが、historyがその前提を壊す
親状態にH経由で再び入ると最後にアクティブだった子へ復帰するため、同じイベントと同じ外側の状態でも異なる内部状態に入ることがありうる
その隠れた「最後にアクティブだった子」自体が状態なのに、ダイアグラムには普通描かれない
Harelの原論文もこれを認めており、SCXMLとXStateも実装しているが、肝心のこの部分はほとんど語られない
だから deep history でサブツリー状態を再入時に保持するなら、bookkeepingをチャートエンジン側へ移したにすぎない
これは妥当な選択ではあるが、図だけでは全体の振る舞いを説明しきれず、history遷移も他の状態ロジックと同様に別途テストが必要だ
後者の解釈なら機械は完全に決定的で、deep historyポインタもただの状態機械状態の一部だ
たとえばH、Hノードを複数ノードに展開し、H'を各ノードの前に付くwrite-ahead logのようなものとして置けばよい
Temporal, DBOS, Restate のようなdurable executionエンジンとstatechartsを組み合わせられるのか気になる
会社ではonboardingとpayment workflowを管理するのにCloudflare Workflowsを使っているが、自動生成されるflowchartダイアグラムのおかげでワークフローの動作をすばやく理解できる
これは結局、statechartsが目指している価値とかなり似ているように見える
https://zindex.ai/
AIが作るダイアグラムはたいてい一度生成して終わるMermaid/SVG/PNGで、更新・検証・diff・再利用が可能な 持続的なダイアグラム状態 がない
Zindexはダイアグラム自体を構造化された状態として扱う
エージェントがDiagram Scene Protocol(DSP)でノード、エッジ、グループ、関係、制約、リビジョンをpatchすると、Zindexがvalidation、layout、rendering、versioning、storageを担う
だからTemporal/DBOS/Restate/Cloudflare Workflowsの横に付けて、実行の信頼できる情報源はエンジンが維持し、Zindexはコードや実行履歴から派生した永続的で検査可能な視覚モデルを管理させられると考えている
実際、durable executionさえ付けばstatechartsでも十分にできる
Cloudflareがしばらくdurable object actorモデルの方向へ進んでいるように見えたが、そのプロジェクトをやめたのかどうかはよく分からない
Cloudflare Workersに組み込みの機能なのか、それともチームで独自に作ったものなのか知りたい
XState が本当に好きだ
複数のコードベースで数多くの問題を解決してくれたし、最近では銀行向けに作っている音声アプリの中核的な骨格になった
これだけ時間と努力を注いで素晴らしいものを作ってくれてありがとう
finite state machinesの経験と、XState + Mastraで組んだアーキテクチャについてはブログにも少しまとめた
公開後にはMastraから Pipecat に乗り換えた
https://blog.davemo.com/posts/2026-02-14-deterministic-core-agentic-shell.html
これも一緒に投げておく
ETL State Chart と Hierarchial FSM:
https://www.etlcpp.com/state_chart.html / https://www.etlcpp.com/hfsm.html
Quantum Leaps:
https://www.state-machine.com
主にsafety-criticalシステムで使ってきたが、ここでは複雑性、タイミング、動作の検証可能性が特に重要だ
意思決定と行動を分離できる点が大きな助けになる
「今この状態でこのイベントが来たら次に何をするか」で意思決定を削り出すやり方は、普通のプログラム構造とは少し異なるが、分離をうまく作れて、さまざまな条件での動作を推論しやすくなる
状態機械の採用がもっと広がってほしいとずっと思っていた
AIが生成したコードを、人間が書いたコードほど深く理解できない時代には、stateの視覚的理解 がますます重要になる
それでもフロントエンドフレームワークでは依然としてstoreベースのreactive stateが好まれているようだ
私自身もそれをデフォルトで使うほうで、わざわざ切り替えてこなかったし、xstateのようなライブラリには文法を学ぶのがより難しく冗長だという印象もある
だがAIがあればその障壁はほぼ下がるので、私が見落としている別の理由があるのか、それともstatechartがまだ頂点に達していないだけなのか気になる
APIの表面積も減り、学習曲線も下がり、開発者にもエージェントにも書きやすくなる
同時に、最新のfrontierモデルはすでにXStateコードをかなりうまく書ける
https://github.com/xlnfinance/xln プロジェクトを進める中で、実際のネットワークを 決定的にエミュレート する方法が必要だと気づいた
そこで、すべてのブロックチェーンは結局replicated state machineなのだから、各ユーザーノードを Runtime -> Entity -> Account の 3段階の状態機械階層 で包めばいいのではないかと思うようになった
外側の機械が内側の機械を完全に制御する構造なので、異なる合意モードを持つ「blockchain inside blockchain」のような図になる
その後「hierarchical state machines」を検索してstatechartsを見つけ、この2つのアイデアはかなり似ていると感じた
私としては、より多くのソフトウェアが状態機械階層を使って、非決定性が生む最悪のバグを減らすべきだと思う
自動車分野ではこうしたやり方を 長年 使ってきた
matlab/simulinkを見ると、アルゴリズムを状態機械として描いてコード生成までできる
最近ではかなり複雑なReactコンポーネントを管理するために状態機械を実装したが、CSS transitionを経ながら複数の視覚状態を行き来する構造だった
状態機械そのものはそれほど難しくなかったが、人々はこれにまだ十分慣れていないようだ
会社では私が Postgres内部インタプリタ を作って以来、すべてのビジネスプロセスをstatechartsで回している
体験は非常に良く、プロセスは変化にとても強くなり、数年後に戻ってきても理解しやすい
ライブラリもオープンソースとして公開してある
https://github.com/kronor-io/statecharts