ハクソク

世界を動かす技術を、日本語で。

ステートチャート:階層型状態機械

概要

Statechartは複雑なシステムを視覚的に表現する強力な手法
State machineの課題を解決し、理解・保守性を向上。
SCXMLなどの標準や多様なツール・ライブラリが存在。
利点欠点の両面を理解し、適切な利用が重要。
実行可能なstatechartで設計と実装の一元管理も可能。

Statechartとは何か

  • Statechartは、状態遷移図を拡張した視覚的な表現方法
  • David Harelの論文「A visual formalism for complex systems」で提唱
  • 複雑なシステムの状態管理挙動整理に最適
  • State machineの状態爆発問題を解決
  • 図式表現による直感的な理解促進

State machineとStatechartの違い

  • State machineは単純な状態遷移モデル
  • Statechartは階層・並列・履歴などの拡張機能を持つ
  • 複雑な状態・例外処理の整理に強み
  • 保守性可読性テスト容易性の向上

Statechartの利点

  • コードよりも理解しやすい視覚的表現
  • 挙動の部品化により変更容易
  • 独立したテストが可能
  • 設計過程で全状態の網羅を促進
  • バグの減少例外ケースへの強さ
  • スケーラビリティの高さ
  • 非開発者QAも理解・活用可能
  • 既存コードにも隠れた状態機械が存在

Statechartの欠点・課題

  • 学習コストの発生
  • 従来の開発手法と異なるため、チーム内抵抗
  • 小規模なstatechartではコード量が増加する場合
  • 導入自体が不要とされるケース(YAGNI原則)
  • 技術スタックとの相性問題
  • ライブラリ増加によるロード時間増加(特にWeb)

Statechartがあまり使われない理由

  • 認知度の低さ
  • **YAGNI(You Aren't Gonna Need It)**の思想
  • 必要性を感じにくい現場も多い

Statechartの利用方法

  • SCXML(Statechart XML):W3C標準の状態遷移記述フォーマット
    • 10年以上かけて策定
    • 多言語対応ツール・ライブラリが存在
  • SCXML互換ライブラリ:各種プラットフォームで利用可能
    • エッジケース処理や正しい遷移順序の自動化
  • ビジュアルエディタ実行環境の活用

実行可能なStatechart

  • 設計図と実装の一元化が可能
  • JSONXMLファイルで状態定義し、図と実行を連携
  • 利点
    • 図とコードの同期
    • 手作業によるバグの回避
    • 精密な図の自動生成
  • 欠点
    • 図の複雑化
    • ツールやフォーマットの制約
    • 型安全性の担保が難しい場合

Statechartのリソースとコミュニティ

  • gitter.im:チャット形式の開発者コミュニティ
  • GitHub Discussions:Q&Aや情報交換の場
  • 書籍・発表資料:さまざまな解説リソース
  • ユースケース例(UIなど)、用語集FizzBuzz問題による解説も存在

まとめ

  • Statechartは複雑なシステムの状態管理に非常に有効
  • 利点欠点を理解し、プロジェクトに応じて導入を検討
  • 標準規格・ツール・コミュニティの活用で導入障壁を下げることが可能

Hackerたちの意見

2時間経ってもコメントがゼロ?!一時期、Statechartsはフロントエンド/UIエコシステムで注目されてたけど、ほんの少しだけどね。状態遷移図(特にStatecharts、つまり状態機械の組み合わせ)を使うことで、UIの複雑なフローを考えるのがめっちゃ楽になるんだよね!でも、残念ながらその注目は理由もわからず消えちゃったみたい。もしStatechartsを初めて聞いたなら、Ian Horrucksの「Constructing the user interface with statecharts」って本を超おすすめするよ(https://archive.org/details/isbn_9780201342789/mode/2up)。1999年の本だけど、Statechartsの使い方を学ぶには最高の入門書だと思う。
> Statecharts seemed to be getting traction in the frontend/UI ecosystem そうそう、GodotのプラグインをチェックしてたらStatechartsに出くわしたよ!: https://github.com/derkork/godot-statecharts
状態遷移図はまだ注目されてるよ!XStateは週に400万回以上npmでダウンロードされてる。RiveやLottieFilesみたいなアニメーションツールも状態機械の機能を大々的に宣伝してるし、LangGraphみたいなAIツールも状態機械の基盤の上に作られてる。これらのアプリやツールが状態遷移図の可能性を最大限に引き出すには時間がかかるだろうけど、いいスタートだね。
Statechartsがまだ注目されてるのを見ると嬉しい!XStateっていうJS/TSライブラリを作ったんだ。状態機械や状態遷移図を作成、実行、可視化するためのやつね: https://github.com/statelyai/xstate。もう10年以上取り組んでるよ。学んだことは、状態遷移図はドキュメントとしてだけじゃなく、実行可能な振る舞いとして扱うと最も価値があるってこと。どこでも使う必要はないし、すべてをモデル化する必要もないけど、「次に何が起こる?」っていう答えが現在の状態とイベントの両方に依存する振る舞いにこそ、役立つんだ。状態遷移図は「この状態にいるとき、このイベントが起きたら次の状態は何で、どんな効果が実行されるの?」っていう質問のオラクルみたいな役割を果たすよ。次のメジャーバージョンのアルファ版をリリースする準備が進んでて、より使いやすさ、型安全性、コンポーザビリティに焦点を当ててるんだ。それに新しいビジュアライザー/エディターもあるよ。基本的な状態遷移図のオープンソースビジュアライザーもここにあるよ: https://sketch.stately.ai。正式な仕様についてはSCXMLも読む価値があるよ: https://www.w3.org/TR/scxml。デビッド・ハレルのオリジナルの論文も読む価値あり: https://www.weizmann.ac.il/math/harel/sites/math.harel/files...
XStateを使ったことがあって(今でも喜んで使うけど)、その「状態遷移図」が何を意味するのかも知らなかったんだ。lit.jsと一緒に使って、ページ幅に反応する引き出し型のナビゲーションコンポーネントを作ったんだけど、XStateがなかったらどれだけひどかったか考えられないよ。本当にありがとう!
Clojureの人たちには、XMLの要件を排除したかなり洗練された実装のhttps://github.com/fulcrologic/statechartsがあるよ。特に実行可能なコンテンツに関してね。それでもSCXMLに近い感じ。XStateは先行技術のセクションでも言及されてるし。
XStateは素晴らしいライブラリだよね!新しいメジャーバージョンとビジュアライザーが出るって聞いてワクワクしてる。 :)
Xstateは過去にいくつかの厄介な状況を解決するのに助けてくれたよ。次のバージョンが楽しみだし、素晴らしい仕事に感謝してる!
Xstateには敬意を表するけど、複雑なネストされたステートマシンが必要ないなら、robot3.jsをチェックしてみて。自動的なTS型推論があって、ステートマシンのロジックをちょっと使いたいところには便利だよ。
XStateは素晴らしいね、複雑な分散型キー共有スキームが簡単にできたよ。
あなたは詳しいみたいだけど、ペトリネットについて何か意見ある?
あなたのおかげで、初めてステートマシンを知ることができたんだ!これはLaraconで話した内容で、ステートマシンやステートチャートについての考えをまとめたものだよ。 https://www.youtube.com/watch?v=1A1xFtlDyzU
タイトルには「階層的」って書いてあるけど、投稿の中には戻ってこないね。多分、階層が必要なんだろうな。そうじゃないと状態遷移図が大きくなりすぎちゃう。
階層なしの状態遷移図はただの状態機械だよ。構成と階層があって初めて状態機械が状態遷移図になるんだ。
「What is a statechart?」をクリックすれば分かるよ、https://statecharts.dev/what-is-a-statechart.html 。> ステートチャートの主な特徴は、状態が階層的に整理できることだ。ステートチャートは、各状態が自分の下位状態マシン(サブステート)を定義できるステートマシンだ。その状態もまたサブステートを定義できる。
状態遷移図をTemporalやDBOS、Restateみたいな耐久性のある実行エンジンと組み合わせることは可能かな?うちではCloudflare Workflowsを使ってオンボーディングや支払いのワークフローを管理してるんだ。ワークフローが何をするのかをすぐに理解できるフローチャートの図を生成してくれるから、状態遷移図が目指してることと似てると思う。
「フローチャートの図を生成する」って言うけど、具体的には何がそれを生成してるの?Cloudflare Workersに組み込まれてるのか、それとも君たちのチームが作ったものなの?
そうなんだよね、ワークフローが注目されがちだけど、ステートマシンも十分に能力があるのに。ステートチャートのためには耐久性のある実行が必要なんだ。Cloudflareはしばらく耐久オブジェクトアクターモデルに取り組んでたみたいだけど、そのプロジェクトはどうなったか分からないな。
お気に入りのデータ構造の一つだね。少し前にObjC/Swift用のStateKitを作ったんだけど、いくつかの大規模なアプリで実際にテストされてるよ: https://github.com/sghiassy/StateKit。めっちゃクールなデータ構造だよね。
これ、もう自動車の分野では長いこと使われてるよね。matlab/simulinkを見てみて。アルゴリズムを状態遷移図として描いて、そこからコードを生成できるんだ。最近、結構複雑なReactコンポーネントを管理するために状態遷移図を実装したんだけど、CSSのトランジションを使って視覚的な状態を移動させるものだった。そんなに難しい状態遷移図じゃないけど、みんなあんまり詳しくないと思う。
ゲームエンジンにはもうこれか、それに近いものが実装されてるんじゃないかな。
フロントエンド開発で状態遷移図を使おうとしたことが何回かあるけど、うまくいかなかった。確か、xstateをvueで使ってたんだけど、既存のシステムに適応させるのが難しかった。試したところでは、xstateが制御するシステムの部分と他の部分の境界が問題だった。状態遷移図の「中」にすべてを入れた方がうまくいく気がしたけど、それは既存のコードベースには大変な作業だよね。
ちょっと興味があって聞くけど、それはLLMエージェントの前?それとも後?
ずっと前に、状態遷移図の波括弧エンコーディングからJavaへのコンパイラを書いたことがあるんだ。最近では、SwiftUIの初期のバグを避けるために、iOSアプリのインタラクションを状態遷移図でモデル化して、コード内のASCIIアートコメントにして実装したよ。
入門書でよく見落とされることの一つは、履歴擬似状態(H, H)が外部から見るとステートチャートを形式的に非決定的にするってこと。要は「現在の状態は入力の純粋な関数」ってことなんだけど、履歴がそれを壊しちゃう。`H`を使って親に入ると、最後にアクティブだった子に入るから、同じ外部状態からの同じイベントが2つの異なる内部状態に入ることがある。あの潜在的な「最後にアクティブだった子」は状態そのもので、ただ図には描かれない状態なんだ。ハレルの元の論文でも認められてるし、SCXMLとXStateもそれを実装してるけど、誰もあまり話さないね。だから、再入場の際にサブツリーの状態を保持するために深い履歴(H)を使ってるなら、帳簿管理をチャートエンジンに移したってことになる。まあ、それはいいけど、図だけでは全体のストーリーが伝わらなくなっちゃうし、履歴遷移には他の状態と同じように独自のテストが必要なんだ。
ステートチャートって、機械制御にめちゃくちゃ役立つ概念なのに、あまり普及してないのが不思議だよね。せいぜい、フラットなミーリー状態機械について知ってる人が多いくらい。グラフィカルにHSMをデザインして、いろんなシナリオでシミュレーションして検証して、コードを自動生成するのが一番いいと思わない?