07. 進化条件(ADRと境界の強化タイミング)
目的
- 「いつ境界を強めるか」を、観測可能な条件(S/D/V の悪化、運用要件)で判断できるようにする
- ADR を最小限に運用し、意思決定の再現性と合意形成の速度を上げる
得られる判断能力
- 「最初から大掛かりにしない」ための進化条件(トリガー)を定義できる
- 進化の根拠を S/D/V と運用要件で説明できる(気分で境界を増やさない)
- ADR を最小運用し、意思決定を再利用できる形で残せる
前提/用語
- ADR: Architecture Decision Record(意思決定の記録)
- 進化条件: 現状の設計が限界に近づいた兆候(変更の痛み、障害、運用負債)
要点
- 境界の強化は、コストに見合うトリガーが発生したときに行う(先回りしない)
- S/D/V の悪化は「結合の偏り」の兆候。トップ依存の再採点で把握する
- ADR は長文ではなく、Context / Decision / Consequences の最小記録でよい
進化条件(トリガー)の見つけ方
「進化」は理想論ではなく、観測できる痛みから始めます。小規模で有効な観測の例です。
- 変更の痛み(主に S):
- 片方を直すと別の箇所が壊れる(暗黙の契約がある)
- 変更が常に同じ PR に乗る(同時変更が常態化)
- リリース前に統合不具合が繰り返し見つかる(境界の検証不足)
- 距離の痛み(主に D):
UI → API → DBのような遠い経路で障害が起きると切り分けに時間がかかる- 外部 I/F(通知、決済、認証など)で失敗・遅延・仕様差分が顕在化する
- デプロイ単位/責任分界が分かれ、合意と調整がボトルネックになる
- 変動性の痛み(主に V):
- 例外系や分岐が増え、テストが追随できない(仕様が固まっていない)
- 同じルールが複数箇所に重複し、変更漏れが起きる
- 「正しい抽象」を求めて設計が停滞する(固定化し過ぎの兆候)
- 運用要件の顕在化:
- 障害対応が属人化している(復旧手順が暗黙)
- ログ/監視が不足しており、原因が追えない
- 手動リカバリが増え、継続運用コストが上がっている
進化条件は「気分」になりやすいため、Appendix B の Change Drivers テンプレで観測と根拠を先に揃えると再現性が上がります。
トリガー別の最小手当(境界/契約/テスト/運用)
境界強化は「分離する」だけではありません。トリガーに応じて、まず最小コストの手当から始めます。
| トリガー(観測) | 効いている軸 | まずやる手当(最小) | 追加投資(必要なら) |
|---|---|---|---|
| UI/API/DB の不具合が多い、切り分けに時間がかかる | D | 入出力・エラー形式を明文化し、統合テストで固定する(章 05-06) | 契約テスト、ログ/監視、アラート |
| 外部 I/F の失敗が業務影響を持つ | D | 失敗時の期待(業務継続/再送/検知)を受け入れ条件に入れる | adapter 強化(タイムアウト/リトライ)、アウトボックス等 |
| 変更が常に同じ PR に乗る、同時変更が前提 | S | 無理に分離せず、一体として扱う粒度を明確化する | 共有ロジックの集約、責務境界の整理 |
| ルールが重複し、変更漏れが起きる | V | ルール(知識)を domain に寄せ、単体テストで守る | UI/API の重複排除、ガードレール整備 |
| 例外系が増え、仕様が曖昧なまま実装される | V | 受け入れ条件(例外/失敗時)を先に固定する(Appendix B-3) | ADR(重大な分岐のみ)、運用手順の明文化 |
「手当の効果が期待できるか」を判断するために、トリガーは 1〜2 週間単位で見直せる粒度にします(大規模な再設計を前提にしない)。
よくある進化パターン(トリガー→最小手当→次の投資)
進化条件を「あるある」パターンとして整理しておくと、同じ議論を繰り返さずに済みます。以下はランニング例(タスク管理)で頻出する進化パターンです。
1) 通知が“機能”から“運用”へ成長する(通知チャネル/再送/テンプレ)
- トリガー(観測):
- 通知の失敗が業務影響を持つ(問い合わせ/取りこぼしが増える)
- 通知条件が増え、例外系(送達不可、遅延)が顕在化する
- D(距離)が大きい外部I/Fのため、切り分けと再送運用がボトルネックになる
- 最小手当:
- 仕様(Behavior)で「業務継続/検知/再送」の期待を固定する(曖昧にしない)
- 通知は adapter 境界の責務として分離し、ユースケースは通知要求(契約)だけを扱う
- 観測点(ログ/メトリクス/再送起点)を設計し、E2E は到達性ではなく自系の契約を検証する
- 次の投資(必要になったら):
- 再送キュー、アウトボックス、テンプレ管理、通知チャネルの追加(メール→別チャネル)
- 失敗時の判断(停止/継続)を ADR として固定する
2) 権限が増殖する(ロール拡張/例外追加/UIとAPIの不整合)
- トリガー(観測):
- UI と API で権限判定がズレる(見えるができない/できるが見えない)
- 役割が増え、条件分岐が章01の例外系カタログで埋まる
- V(変動性)が上がり、同時変更(S)も増える
- 最小手当:
- 権限ルール(判定)を domain 側に寄せ、UI/API は判定結果を利用する
- 例外系(
403、404の扱い、監査ログ)を仕様として固定し、統合テストで守る - ルールの表(ロール×操作×対象)を最小で作り、変更時の影響範囲を可視化する
- 次の投資(必要になったら):
- ポリシーの外部化(設定化/ポリシーエンジン)、監査要件の強化(閲覧権限/保持期間)
- “誰が何をできるか”の前提が変わる場合は ADR 対象にする
3) 監査/整合性が要件化する(履歴/同時更新/冪等性)
- トリガー(観測):
- 「いつ誰が何をしたか」が追えず、運用復旧が属人化する
- 同時更新や二重実行が増え、データの食い違いが顕在化する
- 障害時の説明責任(監査)が求められる
- 最小手当:
- 監査ログの“最小スキーマ”(actor/対象/時刻/結果/相関ID)を決め、成功/失敗を記録する
- 競合(
409等)と冪等性(二重送信)の振る舞いを仕様で固定し、統合テストで守る - DB 制約(ユニーク、外部キー等)を「仕様の裏付け」として使い、破綻を早期に検知する
- 次の投資(必要になったら):
- 相関IDの全経路伝播、イベントの永続化、非同期処理の整合性(アウトボックス等)
- データ整合性の戦略が変わる場合は ADR 対象にする
補助テンプレ:
- Change Drivers / ADR: Appendix B: テンプレ集(B-6/B-7)
- 外部I/F失敗時設計: Appendix B: テンプレ集(B-16) / 記入例: Appendix D: 記入例(D-24)
例(ランニング例)
タスク管理の進化条件を例にします。
- 通知要件が増え、メール送信が失敗するケースが顕在化した
- 失敗時の扱い(リトライ、監視、手動復旧)が要件化される
- D(距離)が大きい外部I/Fのため、境界(adapter)の責務が増える
- 判断: ユースケースから直接送らず、「通知要求の発行」と「送信処理」を分離する価値が出る
- 権限モデルが拡張され、UI と API の条件分岐が急増した
- V(変動性)が上がり、知識の共有が拡散している兆候
- 判断: 権限判定を domain 側へ寄せ、UI/API は同一の判定結果を利用する
ADR の最小運用(例)
- ADR は「重大な分岐」だけに絞る(例: 通知方式、権限モデル、データ整合性の戦略)
- 1 ADR は 1 決定。議事録化しない
- 見直し条件(いつ再評価するか)を必ず書く
ADR を書くタイミング(実務の目安)
ADR は「後から取り返しがつきにくい」決定に絞ると運用しやすいです。
- ADR を書く(書く価値がある):
- 失敗時の期待が変わる(例: 通知失敗で業務を止める/止めない)
- データ整合性や監査要件が絡む(例: いつ・誰が・何をしたか)
- 境界の責務が増える(外部 I/F、認可、非同期化)
- チーム/運用の前提が変わる(オンコール、SLO、別担当)
- ADR を書かない(テンプレで十分なことが多い):
- 実装詳細の選択(ライブラリ差し替え等)で、後から容易に戻せる
- 影響範囲が狭く、障害時の復旧が単純
ADR を書く前に、Change Drivers(Appendix B-6)で「なぜ今変えるか」を整理しておくと、Context が短くなり議論が収束しやすくなります。
演習(最小1個)
ランニング例で「境界を強めるべき」状況を 1 つ選び、次の順で 1 セット作成してください。
- Change Drivers(なぜ今変えるか)
- ADR(何を決めたか)
- Appendix B: テンプレ集
- Change Drivers: B-6
- ADR: B-7
- 記入例: Appendix D: 記入例
例(題材):
- 状況: 通知(メール)の失敗が業務影響を持ち始めた
- 選択肢: 直接送信 / 通知要求の発行 + 非同期送信 / リトライキュー導入 など
- 目的: 失敗時の取り扱いを明確にし、テスト容易性と運用性を確保する
よくある失敗
- ADR が議事録化し、意思決定の要点が埋もれる
- 進化の根拠が「気分」になり、境界強化が目的化する
- 変更の痛みを可視化しないまま、部分最適なリファクタリングを繰り返す
チェックリスト
- 境界強化のトリガーが明確(S/D/V、運用要件、変更頻度)
- Change Drivers(なぜ今変えるか)が短文で整理されている
- ADR の粒度が一定で、検索・再利用できる
- 設計変更がテスト戦略(配分)に反映されている
- 見直し条件(いつ再評価するか)が合意されている