ドメインモデリング
設計しながら、プロジェクトのドメインモデルを能動的に構築し、研ぎ澄ませる。これは能動的な規律である: 用語に異議を唱え、エッジケースのシナリオを考案し、それが結晶化した瞬間に用語集や決定事項を書き留める。(用語のために CONTEXT.md を単に読むだけならこのスキルではない。それはどのスキルでもできる1行の習慣にすぎない。このスキルはモデルを単に消費するのではなく、変更しているときのためのものである。)
ファイル構成
ほとんどのリポジトリは単一のコンテキストを持つ:
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
ルートに CONTEXT-MAP.md が存在する場合、そのリポジトリは複数のコンテキストを持つ。マップは各コンテキストがどこにあるかを指し示す:
/
├── CONTEXT-MAP.md
├── docs/
│ └── adr/ ← システム全体にまたがる決定事項
├── src/
│ ├── ordering/
│ │ ├── CONTEXT.md
│ │ └── docs/adr/ ← このコンテキスト固有の決定事項
│ └── billing/
│ ├── CONTEXT.md
│ └── docs/adr/
ファイルは遅延的に作る: 書くべき内容ができたときだけ作成する。CONTEXT.md が存在しなければ、最初の用語が確定した時点で作成する。docs/adr/ が存在しなければ、最初のADRが必要になった時点で作成する。
docs/ にファイルを足したら(ADR がその例)、索引 docs/README.md にパスと一行説明で1行足す。docs/README.md が存在しなければそのとき作る。索引も遅延的に作るものであり、空の docs/README.md を先回りして置かない。
- `docs/adr/0001-event-sourced-orders.md` — 注文をイベントソーシングで持つ決定(採用)
セッション中に行うこと
用語集に照らして異議を唱える
ユーザーが CONTEXT.md の既存の用語と矛盾する用語を使ったら、即座に指摘する。「あなたの用語集では『キャンセル』はXと定義されていますが、今のはYを意味しているように見えます。どちらですか?」
曖昧な言葉を研ぎ澄ませる
ユーザーが曖昧・多義的な用語を使ったら、正確な標準用語を提案する。「『アカウント』とおっしゃいましたが、Customerのことですか、それともUserのことですか? それらは別物です。」
具体的なシナリオで議論する
ドメインの関係性が議論されているとき、具体的なシナリオでストレステストする。エッジケースを突くシナリオを考案し、概念間の境界についてユーザーに正確さを求める。
コードと照合する
ユーザーが「これはこう動く」と述べたとき、コードがそれと一致しているか確認する。矛盾を見つけたら表面化させる。「あなたのコードはOrder全体をキャンセルしますが、今、部分キャンセルが可能だとおっしゃいました。どちらが正しいですか?」
CONTEXT.mdをその場で更新する
用語が確定したら、その場で CONTEXT.md を更新する。まとめて後回しにしない。起きたその瞬間に捉える。書式は CONTEXT-FORMAT.md を使う。
CONTEXT.md には実装の詳細を一切含めないこと。CONTEXT.md をspecやスクラッチパッド、実装判断の置き場所として扱わない。これは用語集であり、それ以外の何物でもない。
ADRの提案は控えめに
以下の3つすべてが真であるときのみ、ADRの作成を提案する:
- 元に戻しにくい: 後で考えを変えるコストが無視できない
- 文脈なしでは意外: 将来の読者が「なぜこうしたのか?」と疑問に思うだろう
- 本物のトレードオフの結果: 本当に別の選択肢があり、特定の理由でその1つを選んだ
3つのうち1つでも欠けていればADRは不要。書式は ADR-FORMAT.md を使う。