はじめに
私はアジャイルな開発手法の実践を通じて顧客の内製支援を行うグループに所属しており、今までウォーターフォールな文化で開発をしてきた顧客と、1年ほどスクラムを採用したプロダクト開発の支援に携わっています。
今参加しているチームでは、ソフトウェアアーキテクチャに関する意思決定の記録としてADRを作成する文化が育っており、現在では100件ほどのADRが作成され、チームメンバーの誰もがADRを作成するようになっています。
この記事では、どうやってADRを導入し、その運用を続けているのかを紹介します。導入と運用を分けて、チームの状況に合わせてどう進化させてきたかという実践知を共有します。
ADRとは
設計書や構成図などは、最終的に決定したソフトウェアアーキテクチャの「What」を説明してくれますが、どのような意思決定のもとにそこに辿り着いたのかの記載が不足することが多く、数ヶ月経過した後や新しく参画したメンバーは、後からその意思決定を追跡できる状態にはなっていないことが多いです。
この状況の解決のために、ソフトウェアアーキテクチャの決定の記録を残すADR(Architecture Decision Record)という「Why」を記録するためのドキュメント形式が存在しています。
詳細の説明は下記をご参照ください。
アーキテクチャの記述方法は状況に応じて選択する
ソフトウェアアーキテクチャの記述方法のアプローチは、ADRに限らず、「Design It!」で語られている通り、変更頻度や共有の方法に応じてアプローチを変える必要があります。
「Design It!」第11章 アーキテクチャを記述する より
プロダクトのフェーズとチームの文化の進化具合に合わせて、アーキテクチャをどう共有し記録するのかを選択することが重要です。チームメンバーの習熟度や成熟度を考慮して、現状のチームの課題にあった形式でアーキテクチャの決定記録を残すことが大切であり、ADRはあくまでもその一形態です。
フェーズ1:いきなりADRから始めない
チームの状況
私が参加したチームでは、顧客のプロダクトオーナーや開発者など、同じグループから参加したメンバー以外は全員今までウォーターフォールのプロジェクトに参加した経験しかなく、ADRなどを作成する文化も経験したことがありませんでした。
そこでチームの立ち上げにあたり、最初の3週間程度はフル出社を前提とした体制をとりました。フルリモートは、そもそもチームがお互いに率直に意見を言える関係性が整っているからこそ有効にワークします。まずは文化作りを優先し、スクラムを体感することを優先しました。
なぜ「部族的な方法」を選んだのか
ここでは、ホワイトボードと口頭での合意形成を中心に、その場にいるメンバーの記憶に依存したやり方を「部族的な方法」と呼ぶことにします。ドキュメントとしては最低限の記録にとどめ、議論のコンテキストはその場の会話に載せる、というスタイルです。
特にプロジェクトの初期段階では、スプリントごとにソフトウェアアーキテクチャを進化させていく可能性が高く、一度決めた設計方針も、前提条件の見落としやさらに良いアイデアの発見によって変更することが頻繁にあります。都度ADRなどの形式的な方法を採用していると、かなりの頻度で変更することが必要になり執筆コストもかかります。
そこでホワイトボードと口頭での議論をもとにソフトウェアアーキテクチャの決定記録を残す運用を採用し、変更もしやすい状態にし、アーキテクチャをアジャイルに考えていく経験をチームで積んでいくことから始めました。
具体的な方法
最初の数週間は意図的にフル出社するようにしていたので、ホワイトボードにトピックを記載しておいて、誰でもいつでも確認できるようにしていました。ホワイトボードの余白が足りなくなってきたときからは、MiroボードにAWSのアーキテクチャやコード設計を記録するようにしていました。
ただ、この時点では意思決定の理由(Why)までは詳細に記載しておらず、会話した結果(What)を残していた状態でした。少人数で同じ場所にいて、同じ議論を経験したメンバー同士なら、これでも問題なく機能していました。
フェーズ2:ADRの導入
進化のきっかけ
チームが順調に動き始めて1ヶ月が経ち、過去の決定事項を会話する頻度が増えてきました。少人数だったので会話で解消していましたが、改めて明記しておく必要性が高まってきていました。
ADRのような形式的な方法への移行を検討すべきシグナルとしては、以下のようなものです
- 「あれ、これ前にも話しませんでしたっけ?」という会話が増えてきた時
- 新しくメンバーが入ってくることがわかっている時
- チームの中で曖昧なまま進めている事項が多いと感じた時
勉強会を通じた導入
私たちのチームでは朝の9時から9時30分は勉強会開催枠をとっており、自主的な勉強会の開催を行っています。おおよそ週に3回程度勉強会を行っています(最近はほぼ毎日です)。この勉強会の時間を活用してADRの導入を進めました。
勉強会は現状の課題に焦点を当てる形式で説明を行いました。具体的には、従来の基本設計書などには「What」は記載されているが、なぜそのアーキテクチャにしたのかの背景(Why)は記載されていないことが多い点に焦点を当てました。また、こうした背景を明確にしておくことで、元の知識に詳しくない人でもキャッチアップしたり、学習するための土台となることも伝えました。
最初の導入方法
最初はテンプレートを用意して自分が実サンプルを作成しました。ログレベルの決定事項やテスト戦略に関する決定事項を記録し、一度同期的な会話をしながら疑問点を拾い上げつつ詳細部分を記録することで導入を行いました。
基本的に新規の決定から始めていきながら、過去のものはその当時に会話して決めた内容を作成して、非同期的にレビューを行って内容を記録しました。同時編集やコメントも容易であること、他のWikiなどに合わせてNotionでADRの運用を始めました。
テンプレートとしては、以下のようなよくある形式です。(いくらか簡略化しています)
# タイトル
- ステータスに合わせてタイトルを記載する
- 「hogeの設計」などの体言止めではなく、「hogeはfugaとする」といった簡潔で説明的なタイトルにする
## ステータス
- ドラフト、提案中、承認、棄却、代替
## コンテキスト
- その決定が求められている背景、事実情報、関連資料を記載する
- 各方針の比較を行う
## 決定事項
- 最終的に決定した事項と、その理由を記載する
## 影響
- 決定事項が及ぼす、ポジティブ・ネガティブな影響を記載する
- 他チームへの影響や、SLOなどへの影響懸念や、可用性などの品質特性への影響を記載する
フェーズ3:運用の定着
ADRを導入してよく起きがちなのは、導入したメンバーだけがADRを記述するが、チームメンバー全員には広がっていない状況です。こうした状況を避けるために、スクラムに合わせてADRの扱いも明示的に定める運用を行っています。
スクラムへの組み込み
スクラムでは、スプリントでPBI(プロダクトバックログアイテム)に着手できる状態にするリファインメントの活動があり、我々のチームでは完成の定義として何を必須で行うべきか、という会話もしています。完成の定義には、パイプラインでテストがPASSしていることや、必要とされるドキュメントを書いているのかや、どの環境までデプロイするのかなどを毎回話しています。
この時に事前にADRを作成するかどうかも会話して決めており、誰が担当者になったとしてもADRの作成を行うように運用を行っています。
同期と非同期の使い分け
ADRを作成する際にも共有方法は内容に応じて使い分けています。
- 難しい内容:同期的に会話して、そもそもの解決すべき課題を明らかにしたり、いくつかの案の比較検討を行いながら、最終的に非同期的にレビュー依頼を出す
- 軽い内容:PBIを担当する人が自身でアイデアを記載して、そのまま非同期レビューに出す
テンプレートに従うことである程度のばらつきは減っています。また、times(雑談・メモ用チャンネル)やレトロの工夫を行って、日々もやっとしていることを共有できるようにもしているので、詰まっているところがあった際にサポートしやすい環境作りも行っています。
ADRを「読む」運用
リファインメントでは「なぜ」そのPBIを実現しないといけないのか、という背景や目的を深ぼることを目的にしています。チームで背景などを会話する際に、自然と過去のADRを参考情報としてリンクを残すようにできています。
下記のように、PBIのテンプレートとして背景や目的、参考情報を記述する箇所があるため、リファインメントを行う際に担当者が目を通しておくべき過去のADRのリンクの共有なども行い、日々のPBIに着手する中でADRに日常的に触れる機会を設けるようにしています。
背景: aaa
目的: bbb
参考情報:
- ADR-023: hogeはfugaとする
- ADR-041: xxxはyyyを採用する
また、昔から参画しているメンバーが、過去に関連して検討した内容があったことを記憶しており、PBIの参考情報として記載することで、人による橋渡しも行っています。こうした「自然とできている」状態は、日頃からADRに関する会話をしていることの影響だと思います。
決定が覆ったときの扱い
アジャイルでは前提が変われば決定も変わります。過去のADRが「もう当てはまらない」となったときは、過去のものはSuperseded(代替)として、新しく決定事項を作成するようにしています。
その際に、粒度が広いADRは、目的に合わせて単一責任になるようにADRを分割するなどを行っています。コードのリファクタリングと同じ発想で、ドキュメントも適切な粒度に保つことを意識しています。
まとめ
よくソフトウェアアーキテクチャの決定記録を残すためにADRを採用する話はありますが、ADRはあくまでも記述方法や共有方法の一形態にすぎません。個人的には、最初から必ずADRがあるべきだとは考えておらず、チームの成熟度や現状の課題に即して導入をしていくのが良いだろうと考えています。
また、ADRの導入以外にも以下のような活動も一緒に行うことが重要だと感じています
- 仕組み:テンプレートやフォーマット、ツールの選定
- プロセス:スクラムイベントのどこで作成・レビュー・参照するかの取り決め
- 文化:日常的にADRの話題が出たり、PBIや会話の中で自然に参照される習慣
ADRが機能するためには、仕組み・プロセス・文化の3つの層で支える土壌を作ることが大切です。改善点を感じた場合は即動く、というアジャイルな姿勢で、これからもチームに合わせて進化させていきたいと思います。
