ADRとは一体何なんだ
ADRは「決めたことを書く場所」じゃなくて「決め方を残す場所」だよねという話です。
今日は書き方変えてフランクに行きます。
はじめに
最近、フロントエンドのプロフェッショナルとして色々やってきたいなって思った。アーキテクチャとか、個人的にはエンジニアリングとか、マネジメント系にも若干は興味が湧いてきたつもりだ。
ADR(Architecture Decision Record)を導入している現場は増えてきた。増えてきたんだけど、「で、これ何のために書いてるんだっけ?」が曖昧なまま運用されているケースもけっこう見る。実際、僕の友達も、ADRみたいなのは書いてるんだけど、運用が曖昧で良く分かってないし見てもないみたい。
最近そのへんについて考える機会があったので、自分の整理も兼ねて書いておく。
ADRって何
ざっくり言うと「なんでこの技術/設計を選んだのか」を残しておく文書。
たとえば「メッセージキューにKafkaを使うことにした」みたいな決定があったとき、決定そのものだけを残しても半年後の自分や新しく入ってきた人には何も伝わらない。知りたいのはそこじゃなくて、
- そもそも何が課題だったのか
- 他に何を候補にしたのか(SQSは? RabbitMQは?)
- なぜそれらを選ばなかったのか
- この選択によって何を諦めたのか
このへんなわけです。ADRはこれを残すためのもの。
よく使われるフォーマットもだいたいこの形になっていて、Context(背景) / Decision(決定) / Consequences(結果・影響)みたいな構成が多い。ステータス(Proposed / Accepted / Deprecated / Superseded)を持たせて、後から別のADRで上書きできるようにするのも一般的。
何が嬉しいのか
1. 「なんでこうなってるの?」に答えられる
コードを読めば「どうなっているか」は分かる。でも「なぜそうなっているか」はコードには書いていない。
で、その「なぜ」が分からないコードは、だいたい壊される。「この処理いらなくない?」って消したら本番が落ちる、みたいなやつ。逆に「これ変えたいけど怖いから触らない」で塩漬けになるパターンもある。どっちも「なぜ」が失われた結果。
2. 決定を後から覆せる
ADRのステータスが重要なのはここで、「あのときはこういう前提だったから、こう決めた」が残っていれば、「その前提が変わったから、この決定も変えていい」という判断ができる。
前提が記録されていないと、決定だけが独り歩きして「昔からこうだから」という理由で残り続ける。これが一番よくない。
3. 決定にレビューを入れられる
個人的にはこれが一番デカいと思っている。
「決めました」だけだと、それが妥当かどうかを他の人が判断できない。「こういう理由で、これとこれを比較して、こっちを選びました」まで書いてあるから、「いや、その比較軸だと見落としがある」と言える。
ADRは記録装置であると同時に、レビュー装置でもある。
雑な例
めちゃくちゃ雑な例で言うと。
「暑いときに食べるものはホームランバーを食べる」っていう意思決定をしたとして。
ホームランバーが生産終了したとする。
この瞬間に、さっきの意思決定は何の意味も持たなくなる。「暑いときに食べるものはホームランバーを食べる」と描かれた紙だけが残って、どうしようもない。暑いのに。夏なのに。
でももし、ここで「なぜホームランバーだったのか」って書いてあったら?
- 安い。
- コンビニで売ってる。
- 当たりが出るのでお得。
- 片手で食える。
これが残ってれば、仮に生産が終了しても以下をまた意思決定できる。
- 「安さならガリガリ君選ぶよな」
- 「ハーゲンダッツは高いからちょっとダメだな」
- 「あたりが出るんだったらやっぱガリガリ君だよな」
- 「片手で食えるなら爽はないな」
って判断が出来る。
決定だけが残ってても意味が無くて、前提が崩れた瞬間に詰む。そうじゃなくて、背景が残ってたら、後々前提が崩れても選びなおせるよなと。
これがADRのウマ味だと思う。
粒度の話
ここからが本題。
ADRって何を書くもの? を突き詰めると「アーキテクチャ上の意思決定」なんだけど、この「アーキテクチャ上の」が案外効いていて、要するに後から変えるのが高くつく決定のことだ。
- 言語を何にするか → 後から変えるの、めちゃくちゃ高い。ADR案件
- ドメインをどう分割するか → 後から変えるの高い。ADR案件
- 認証をどう扱うか → 高い。ADR案件
- このテーブルにこのカラムを足すか → マイグレーション書けば終わり。ADR案件じゃない
最後のやつをADRに書き始めると何が起きるか。ADRが読めなくなる。
500行のADRのうち450行がテーブル定義だったとして、その中に埋まっている「なぜこのドメイン分割にしたのか」という10行を、誰が見つけられるのか。というか、そもそも読み通せるのか。
読まれないADRはレビューされない。レビューされないADRは、ただの「決定の通知」になる。
「決定の通知」になったADRは何なのか
で、ここが個人的に一番引っかかっているところ。
ADRという形式は、それ自体がある種の権威を持つ。「ADRに書いてあります」と言われると、なんとなく「ちゃんとした手続きを経た決定なんだな」と思ってしまう。
でも実際には、ADRはただのMarkdownファイルだし、誰でも書ける。書いた時点では、それは提案でしかない。
細部まで書き込まれた分厚いADRが出てくると、読む側はこう思う。「ここまで書いてあるなら、まあ検討済みなんだろう」と。そして誰もレビューしないまま、それが「チームの決定」ということになる。
実質的には個人の設計がプロセスをすっ飛ばして正式決定に昇格している状態だよな~って思う。しかもADRという形式のせいで、事後的に「いや、それチームで合意してなくない?」と言いづらくなっている。
Proposed → Accepted のステータス遷移が意味を持つのは、その間にレビューがあるからだ。そこが省略されているなら、ステータスはただの飾りになる。
じゃあどうするのがいいのか
粒度を「後から変えるコスト」で決める
さっき書いたやつ。変えるのが安い決定はADRに書かない。コードとマイグレーションで十分。
実装詳細は別ドキュメントに切る
テーブル定義とかAPIスキーマとかは、それ用のドキュメント(あるいはコード自体)に置く。ADRからはリンクだけ張る。
ADRは「なぜその方針にしたか」、詳細ドキュメントは「その方針の具体形」。役割が違う。ADRは法律じゃない。
1 ADR = 1 決定を守る
複数の決定が混ざったADRは、後からステータスを変えられない。「この部分は今も有効だけど、この部分はもう古い」という状態を表現できないから。分けるべきだよね。
まとめ
ADRは「決めたことを書く場所」ではなくて「決め方を残す場所」だと思っている。
- 決定そのものより、背景と却下した選択肢のほうが価値がある
- 粒度は「後から変えるコスト」で決める。細かすぎると読まれなくなる
- 読まれないADRはレビューされない。レビューされないADRは個人の設計書と変わらない
- ステータス遷移は形式じゃなくて、レビューの実在を示すもの
逆に言うと、ADRを導入したこと自体は何も保証しない。フォーマットだけ真似ても、レビューが機能していなければ「ちゃんとしてる感」が出るだけで中身は変わらない。
むしろ「ちゃんとしてる感」が出てしまう分、何もしていないより厄介かもしれない、と最近は思っている。
そう考えると「読んでもらえるようなレビュー」も「読んでもらえるような記事」も似たようなもんだよねと。
余談
ソフトウェアエンジニアリングの基礎 って本が Oreillyから出るらしいので僕は買います。
その前に、デザインシステムとかソフトウェアアーキテクチャとかちゃんと勉強せなあかんなと思いまする。。。。積読が無限に溜まるんじゃ。