TL;DR
この記事では、ソフトウェア開発における重要な意思決定を記録するドキュメント(ADR)について解説しています。
ADRの7つの要件
- 変更容易性、決定時の事実の記録、読みやすさ、決定の妥当性、追跡性、維持管理性、判断軸の明確化
推奨するADRテンプレート構成
- Title: 明確なタイトル
- Statuses: 複数の状態を時系列で管理(Proposed → Accepted → Deprecated等)
- Context: 意思決定の背景(事実のみ)
- Decision Criteria: 選択肢を評価するための判断軸(意思決定の前に定義する)
- Options considered: 検討した選択肢とその利点・欠点
- Decision: 具体的な決定内容(簡潔に)
- Consequences: 決定の結果や影響
- References: 関連ドキュメントやコードへのリンク
判断軸を事前に定義しないと、決定後に都合のよい基準を後付けする HARKing(後付け仮説化) に陥るリスクがある
管理のポイント: 変更履歴が追跡できるプラットフォームで管理
はじめに
昨年もこのアドベントカレンダーに参加しましたが、今年も参加します。
昨年の記事: レガシーコードの本質:読みやすさと持続可能性 #ポエム - Qiita
上の記事で少しだけADRについて触れましたが、今年はADRについて詳しく書きたいと思います。
ADRとは?
Architecture Decision Recordの略で、ソフトウェア開発における重要な意思決定を記録するドキュメントです。
@fuubit さんの次の記事が非常によくまとまっていて参考になります。
アーキテクチャの「なぜ?」を記録する!ADRってなんぞや? #設計 - Qiita
ADRの書き方
ADRの書き方は様々なスタイルがあります。
次のGitHubにて「Template」と調べていただければ、いくつかのテンプレートが見つかります。
正直、書き方はさまざまあり正解はないと思います。個々人の好みやチームの文化によって異なるでしょう。
ただ、ADRの要件定義をすることで、最低限何を書かないといけないかを決めることができると思うため、ここでは私なりに考えるADRの要件とそれを満たすためのテンプレートを紹介したいと思います。
ADRの要件
私が考えるADRの要件は以下の通りです。
| id | 要件 | 説明 |
|---|---|---|
| modifiability | 変更容易性 | ADRはソフトウェア開発の過程で変更される可能性があるため、容易に変更できることが重要です。 |
| known_facts | 決定時の事実の記録 | ADRは、意思決定の妥当性を評価するために、決定時に把握していた事実を記録する必要があります。 |
| readability | 読みやすさ | ADRは、関係者が容易に理解できるように、明確で簡潔な言葉で書かれるべきです。 |
| validity | 決定の妥当性 | 決定がなぜ妥当かを説明する必要があります。これにより、将来の参照やレビューが容易になります。 |
| traceability | 追跡性 | ADRは、関連するドキュメントやコードとリンクされているべきです。これにより、決定の影響を追跡しやすくなります。 |
| maintainability | 維持管理性 | ADRを管理する際に、Declineされた内容が大量に存在すると管理が煩雑になると感じています。 |
| decision_criteria | 判断軸の明確化 | 選択肢を評価するための判断軸(基準)を意思決定の前に定義することで、決定の再現性と再利用性が高まります。後から都合のよい基準を後付けするHARKing(Hypothesizing After Results are Known)を防ぐためにも、事前の定義が不可欠です。 |
ADRテンプレート
構成
私の考えるADRテンプレートは次のような構成です。
| セクション | 関連する要件 | 説明 |
|---|---|---|
| Title | readability | ADRのタイトルを明確に示します。 |
| Statuses | modifiability, maintainability | ADRの状態(Proposed, Accepted, Deprecated, Superseded, Rejectedなど)を示します。 また、一つのADRに対して複数の状態を持たせることができるようにします。 例えば、あるADRが一度Acceptedになった後にDeprecatedになる場合や、軽微な追加修正を行う際に改めてProposedに戻す場合などです。 これにより、ADRの履歴を追跡しやすくなります。 合わせてStatusの変更の際の理由も追加できると良いと思います。 |
| Context | known_facts | 意思決定の背景や状況を説明します。ここでは事実だけを記述し、解釈や意見は含めないようにします。 |
| Decision Criteria | decision_criteria | 選択肢を評価するための判断軸を列挙します。例:「性能」「コスト」「保守性」など。Options consideredの前に定義することで、評価の客観性を担保します。 後から判断軸を追記すると、選んだ選択肢に有利な基準だけを並べるHARKingに陥りやすくなるため注意が必要です。 |
| Options considered | validity | 意思決定の際に検討した選択肢を列挙します。各選択肢の利点と欠点を簡潔に説明します。ただ、これについてあまりにも書きすぎると冗長になるため、重要な選択肢以外は省略しても良いと思います。 |
| Decision | validity | 具体的な意思決定内容を記述します。ただ長すぎると読みづらくなるため、簡潔にまとめます。 |
| Consequences | validity | 意思決定の結果や影響を説明します。ポジティブな内容もネガティブな内容もニュートラルな内容も含めて記述します。 |
| References | traceability | 関連するドキュメントやコードへのリンク(PR、Issueなど)を記載します。 |
テンプレート
# Title
## Statuses
(時系列でdescendingするのが良いと思います)
| Status | Date | Reason |
| ------ | ---- | ------ |
| Deprecated | YYYY-MM-DD | Replaced by ADR-002. Reference to ADR-002. |
| Accepted | YYYY-MM-DD | Initial acceptance by whoB and whoC. |
| Proposed | YYYY-MM-DD | Initial proposal from whoA. Reference to issue #123. |
## Context
## Decision Criteria
(判断軸を先に定義することで、後付け評価=HARKingを防ぐ)
| Criteria | Weight | Note |
| -------- | ------ | ---- |
| 性能 | High | ... |
| コスト | Medium | ... |
| 保守性 | High | ... |
## Options considered
## Decision
## Consequences
## References
ADRの管理方法
ADRを記載するフォーマットは変更履歴が追跡できるプラットフォームであればなんでも良いと思います。例えば、gitのcommit履歴などです。
ただ、そのプラットフォームを使ったとしてコミットメッセージによっては追従しづらい状況になるでしょう。
そのため、いずれにせよ、いつどんな変更が加わったかを追跡できるようにすることが重要だと思います。
余談
ADRを書いたら本当にレガシーコードが減るのか?
ADRを書いておくと、レガシーな内容が発見した際に、その背景を理解しやすくなります。
そのため、背景を改めて確認した後にそれに対して変更を加えることができるかどうかを判断しやすくなります。
よって、レガシーコードを減らす助けになると思います。
ただ、変更を加える際は確証バイアスに注意が必要です。
仮の話ですが、レガシーコードに紐づいたADRを見つけた際に、ADRの内容が大したことがなかったために、レガシーコードを変更したとしましょう。
ただ、暗黙的にそのレガシーコードがあったおかげでバグが発生しておらず、新しいコードに変更したことでバグが発生する可能性があります。
これを踏まえると、ADRを参考にする際は、あくまで参考に留めて、変更を加える際は慎重に行うことが重要だと思います。
変更を加える際も、新しいADRを作成して、変更内容とその背景を記録しておくことが望ましいでしょう。
ADRの実例
以下で、株式会社はてな さんの ADRの取り組みの苦労や成果についてまとめられています。
こちらは、本記事で紹介していない実運用ならではの知見が多く含まれているため、ぜひご覧ください。
ADRを運用して3年経った僕らの現在地 - Speaker Deck
ADRの考え方は他の分野にも応用できる?
ADRの考え方は、ソフトウェア開発以外の任意の場面における意思決定の記録にも応用できると思います。
任意の場面で「この決定をした背景は何か?」という疑問に対して、ADRのフォーマットを用いて記録しておくことで、後から振り返ることができるでしょう。
まとめ
ADRはソフトウェア開発における重要な意思決定を記録するドキュメントであり、変更容易性、決定時の事実の記録、読みやすさ、決定の妥当性、追跡性、維持管理性、判断軸の明確化の7つの要件を満たすことが重要だと考えています。
特に判断軸(Decision Criteria)は意思決定の前に定義することが不可欠です。後から追記すると、結果に都合のよい基準だけを並べる HARKing(Hypothesizing After Results are Known) になりかねず、ADRの信頼性と再利用性が損なわれます。