一休.com Developers Blog

一休のエンジニア、デザイナー、ディレクターが情報を発信していきます

ADR を1年間書いてみた感想

宿泊開発チームでエンジニアをしている @kosuke1012 です。チームで ADR を書き始めて1年くらい経ったので、その感想を書いてみたいと思います。

この記事は 一休.comのカレンダー | Advent Calendar 2023 - Qiita の13日目の記事です。

ADRとは

アーキテクチャ・ディシジョン・レコードの略で、アーキテクチャに関する意思決定を軽量なテキストドキュメントで記録していくものです。

出典はこちらで、

わかりやすい和訳は以下の記事が、

事例は以下の記事が分かりやすかったです。

ADRを導入したねらい

機能を追加したり改修したりする際は、チーム外のメンバー含む様々な人との議論を経て、仕様やアーキテクチャが決定されていくと思います。

そうした議論を経た最終的な決定は実際のプロダクトやアーキテクチャ図などに表現されるのですが、「どうしてそのような仕様やアーキテクチャになっているのか」と言った部分を後から知りたくなったりすることがありました。

これは ADR で解決したい課題そのものと言って良いものなので、チームで ADR を書いていってみよう!という話になりました。

採用したフォーマット

いろいろなフォーマットがあるようなのですが、まずは以下のようなフォーマットで記載しました。

# タイトル
タイトルには、一目で論点がわかるタイトルを記載します。可能な限り具体的で、それでいて簡潔なタイトルを心がけると良さそうです。(これが難しい)

# ステータス
draft, proposed, accepted, rejected, deprecated, superseded

原典のフォーマットには draft はありませんが、この段階で決定を除いて記載しておいて、MTG で決定みたいに進めたいシチュエーションがあったので、追加してみました。
proposed で一旦完成で、チーム(またはチーム間)で合意ができたら accepted にするのが良いかと思います。
別な議論などで決定が覆された場合、当該 ADR の決定を修正するのではなく、当該 ADR (ADR: 1 とする) のステータスを ( rejected: ADR: 2 に伴い ) とした上で、別途新しく ADR を起こし ( ADR: 2 とする )、そのステータスを (proposed: ADR: 1は破棄 ) などとすると良いです。

# コンテキスト
コンテキストには、その ADR の決定が求められている背景や、対応案、対応案に対する評価を記載します。

# 決定
コンテキストを踏まえた決定を、受動的ではなく、肯定的かつ能動的に記載します。

# 影響
この決定の結果生じる影響を記載します。これは、決定の結果得られるメリットのほか、コンテキストで記載した対案を選択しなかった故のデメリットであったりも記載すると良いと思いました。
また、決定の結果、今後チームで意識しなければならないことであったり、改めて必要になる機能やその ADR を記載しても良いと思います。

Michael Nygard さんのフォーマットそのままに draft ステータスだけを追加しています。「ADR を書くときのコツ」の項で後述しますが、draft ステータスは結論が決まっていない段階で ADR を書くのに便利です。このフォーマットで1年運用してみましたが、必要十分だなという感じでした。

ADRの格納場所

私のチームではドキュメントシステムに Confluence を利用していたので、 ADR もそこに記載していきました。そのほかの選択肢としては、プロダクトの GitHub のリポジトリに置く案もあったのですが、そうするとプロダクトを横断する ADR や、具体的なプロダクトが決まっていない柔らかい段階での ADR の置き場に困ったりするので、 Confluence に落ち着きました。

ADR は自分たち以外のいくつかのチームでも書くようになったのですが、その管理方法はチームによりけりでした。
例えば GitHub Projects を利用したタスク管理 - 一休.com Developers Blog のチームでは、ADR 専用のリポジトリを作った上で、GitHub Issues に記載していったようでした。これなら先述の問題はクリアできています。
プロジェクト管理に GitHub Projects を用いている場合は GitHub に一元化することが出来て相性も良いため、GitHub Issues に記載していく方法が良いかもです。

書いてみたADRの例

個々のADR

ADRに番号を振ってプロダクトや案件ごとにまとめています

書いてみてよかったところ

ADR を書いてみてよかったことをいくつか書いてみます。

1. 「ここの設計どうしてこうなってたんだっけ?」に困らない

ADR を書いた1番のモチベーションです。これが解消するのは非常に助かりました。自チームだけではなく、他チームが困っているときに「スッ…」と ADR をスマートに差し出すこともできました。

2. 議論の効率が上がる

以下の複数のポイントで、開発する中での議論の効率が上がりました。

議論が蒸し返らない

1.とも重なるのですが、議論になるような仕様上/設計上のポイントでその背景を思い出すのに手間取ったり、(新事実が見つからない限りは)「やっぱりこっちの方がいいのでは」みたいな話にならないので、議論の効率が上がります。

意思決定するべきことが明確になる

「ADR を書くときのコツ」項で後述するのですが、あらかじめ draft の状態で ADR を記載しておくことで、意思決定しなければいけない項目が明確になり、議論の中であいまいにせず意思決定するようになり、議論の効率が上がります。

意思決定したことが明確になる

ADR を導入してから、MTG の最後に「hoge の件 ADR に書いておきましょう」といった会話が増えました。これによって、意思決定したことをクリアに言語化することになり、議論の効率が上がります。

仕様検討~決定までのフレームワークができる

チームで議論が必要になった際に「じゃ、ADR 書いてまとめておきましょう」という流れができるのが結構良く、検討の中心となるメンバーが増えたり変わったりしてもフレームワークに沿って進めることで議論のレベルを保ちやすくなります。

3. 新規メンバーが立ち上がりやすくなる

新しく参画したメンバーが疑問に思うであろうポイントに ADR があるケースが多いので、キャッチアップしやすいという意見も上がりました。

ADR を書くときのコツ

良い ADR を書くのには割とコツがあることがわかってきたので、気づいた点を書いてみます。

1. タイトルは体言止めにせず、文にする

「hoge について」や「hoge の設計」など、体言止めにするのではなく、「hoge は fuga とする」といったように、タイトルを文にします。

こうすると、タイトルをみるだけで内容が一発でわかるほか、ADR を書く際にも論点がクリアになり、記載や議論の効率があがりました。

2. 結論が決まっていなくても ADR を書きはじめてしまう

結論が決まっていない段階であっても ADR を書きはじめることで、何を決める必要があるのかが明確になってよかったです。
未定のところは実際に hoge などと書いておいて、それを元に議論して、決定事項で hoge を埋める感じです。

3. コンテキストを SCQA フォーマットで書く

コンテキストの章で、結論に至るまでのギャップをいかに埋めるかというのが大切なのですが、これが慣れるまで結構難しいです。

その際のフォーマットとして、SCQA というのが有用でした。『考える・書く技術』という本で紹介されているフォーマットなのですが、

  • S: Situation 状況
  • C: Complication 複雑化
  • Q: Question 疑問
  • A: Answer 答え

Situation でまず状況の説明をして、それに続く Complication で、今回の Question やその Answer が必要になるトリガーを説明します。

www.diamond.co.jp

上で記載した ADR の例で行くと、

S:

(Slack リンク) での記載の通り、未付与のトランザクションに対して、PayPayの取消が発生することは考えられる。

C ~ Q :

この場合に、
1. 新たに取消トランザクションを作成した上で、新規と取消のトランザクションを見て付与取消バッチに判断してもらうのか
2. 既存のトランザクションを論理削除するのか
の2通りの対応がありうるが、どちらにするか。
1.のメリットとしては、
...
などのメリットがある一方で、
...
というデメリットはある。

のような感じです。

このフレームワークは、ADRに限らず、割と複雑な PR の Description を書く際にも有用だなと思いました。 ちなみに SCQA フォーマットは『スタッフエンジニア』という本でも紹介されていて(私もそれで知りました)、
曰く、

多くの議論で、冒頭の段落が巧みに構成されているだけで重要な対話に火が灯る。

だそうです。シビれますね。 bookplus.nikkei.com

4. コンテキストに、もうほぼ結論の手前まで書いてしまう

前述の通り、コンテキストで背景の共有 → 問題意識の共有、と進めた上で「決定」の項目で結論を書くのですが、コンテキストにどこまで書くかというのが悩みどころです。

これは好みもありますが、もうほぼほぼ結論の手前まで「コンテキスト」の項目に書いてしまえば良いと思いました。

コンテキストで結論の手前まで書いた結果、読み手が「決定」を読んだ感想としては『でしょうね~』となるくらいまで書いてしまって良いのではないかなと思います。

5. とにかく軽量にする

優先順位として、
開発する中での重要な意思決定の記録を漏らさないこと > リッチな ADR を書くこと
として、1つ1つの ADR を軽量にして、記載するハードルを下げることを意識すると良さそうです。

1つ1つの ADR にあまり力を入れすぎると、だんだんと書かなくなっていってしまうことがありました。

6. アーキテクチャに限らず、仕様上の決定も ADR に記載していく

ADR はアーキテクチャ以外の決定の記録にも有用でした。それらの決定が、アーキテクチャ上の決定に影響を与えることもあるため、同じ ADR として並べて管理しておくと便利でした。

ADR では足りないところ

ここまで説明してきた ADR ですが、それだけでは足りないなと思う部分もありました。

検討する単位が大きいものを1つのADRで書こうとするのは厳しい

「hogehoge の仕様検討、といった粒度のものを一つの ADR がチームで出てきたのですが、決める論点が多かったり、発散したりしてしまってあまりうまくいかなかった」という意見がありました。

「ADR を書くときのコツ」の項に「タイトルは体言止めにせず、文にする」「とにかく軽量にする」と記載しましたが、逆に言うと、これが出来ないようなテーマについては、ADR には向かないのではないかと思いました。

「全体として今どうなっているのか」を示すドキュメントはADR とは別にほしい

ADR は、ここの意思決定やその背景を記述するドキュメントですが、それに加えて、やはり「全体として今どのような設計になっているのか」といったドキュメントは必要だなと思いました。いわゆる Design Docs がそれにあたると思います。

Design Docs があり、その個々の設計に至った意思決定やその背景がADRとして残されていると理想的なのではないかと思います。全体としての What を Design Docs に記載して、Why を ADR でサポートするイメージでしょうか。

Design Docs とのすみわけ

Design Docs には、Why に答える項目を含めたフォーマットもあったりするので、チームの中で ADR と Design Docs のすみわけの指針がそろっていると良さそうです。一つの観点として「Design Docs が実装でのフィードバックに基づいて継続的に更新される性質を持ち、一方でADRはスナップショットである」という性質の違いがありそう、との意見が出ました。

以上から、Design Docs と ADR の性質の違いをまとめてみます。

反映するもの 時間軸 答える対象
Design Docs (特に実装以後) 実装 What
ADR 意思決定 スナップショット Why

表中 Design Docs と ADR としてまとめていますが、必ずしもそれぞれのフォーマットでフルに記載する必要はないかもしれません。 例えば ADR はログの形で簡易的に記載していったり、逆に Design Docs も必要な部分だけ記載する、といった判断もあるかもしれません。

これらの項目があることを考慮しておくと、必要十分なドキュメントを用意していけるのではないかと思いました。

さいごに

一休では、ともに試行錯誤しながらよいサービスを作ってくれる仲間を募集しています! www.ikyu.co.jp

カジュアル面談も実施していますので、ぜひお気軽にご連絡ください!

hrmos.co