# GUI知識

Rootから始まる階層に画面と部品を組み立て、表示、操作の通知、操作の処理を分ける。

## Rootから始まる階層

Rootが画面を組み立て、画面が領域や表示部品を組み合わせる。画面に独立した操作領域がある場合は、各領域のMediatorが、その領域で完結する状態と操作を管理する。表示部品は担当する領域へ操作の意図を通知し、複数の領域が共有する状態や領域間の調整は親が受け持つ。

状態は、同じ値を使う範囲と、その値が残る時間に合う画面や領域で管理する。

## Passive Viewの役割

Passive Viewの表示部品は、上位の画面や領域から渡された表示内容と操作の可否を描画し、利用者の操作の意図を担当する画面や領域へ通知する。操作を受理または拒否する判断、その後の通信・遷移・次状態の決定を表示部品へ持ち込まず、画面や領域が処理を受け持つ。

部品内だけで使う入力途中の値や開閉状態は、その部品で管理する。複数の部品が扱う対象の識別子や処理の進行状態は、それらを調整する画面または領域で共有する。複数画面にまたがって長く残る値は、その寿命と利用範囲に合う共有管理元で扱う。

## Chain of Responsibilityで未担当の操作を渡す

部品が担当しない操作は、操作の通知を受けた上位へ順に渡す。各階層は自分が担当する操作だけを処理し、処理した操作を別の階層で再実行しない。

## Mediatorで状態に応じて処理する

Mediatorは操作の通知を受け、現在の状態と対象を見て、操作を受け入れるか拒否するか、受け入れた操作に必要な処理、次の状態、表示を決める。表示内容だけでなく、操作の可否と表示対象・処理対象の整合も同じ判断から定まる。同時に実行できない操作は、処理中の再実行を防ぐ。

操作要素の無効化やモーダル表示だけに依存せず、クリックやキーボードなど異なる入口からの通知も同じMediatorの状態判断を通す。操作を受け入れた場合だけ処理を開始し、拒否した操作は処理を開始せず、その場で結果を示す。成功、失敗、入力不備、権限不足などの結果を状態へ反映して表示を更新する。未担当の操作だけを上位へ渡す。

確認への回答を待たずに、対象や入力、保存状態など、判断の前提を変える操作は処理担当が拒否する。確認対象に影響しない独立した操作は、仕様が許す範囲で継続できるようにする。処理中も同じように、同じ処理の重複実行や競合する操作を止める範囲と、独立して続けられる操作を分ける。

Mediatorは、現在の状態と操作から次の状態を決める状態機械として振る舞う。props、callback、binding、hook、Context、form actionなど、フレームワークの標準の仕組みで役割を実現できる。祖先が渡したcallbackやContextの操作で、担当する画面や領域へ直接通知できる。処理担当が現在の状態に応じて操作を受理または拒否し、処理後の状態と表示を決めることを確認する。

## 参考資料

- Martin Fowler: Passive View
  https://martinfowler.com/eaaDev/PassiveScreen.html
