ADRを書くべき理由
(github.blog)ADR = Architecture Decision Records
アーキテクチャ上の決定を、なぜそのように下したのかをコードベース内に記録しておくこと。
GitHub は iOS/Android モバイルチームでこれを導入しており、なぜ必要なのかを説明した記事。
あなたのためではなく、未来のあなたのためのもの
ADR は、自分が下した決定を振り返るためのものではなく、今から 6〜12 か月後に、このアーキテクチャを決めたときのマインドセットを思い出す助けになる。
ADR は、決定が下される時点を捉え、会議、Zoom ミーティング、Slack、コードで扱われた PoC に至るまで、すべてを含む。
頭の中にあるこのコンテキストを言葉として引き出し、後でこのアーキテクチャを見直すときに、そのコンテキストを再び頭に入れられるようにするもの。
本当のボーナスは、数か月後に誰かが GitHubAPIClient モジュールがなぜこのように動くのかと、あなたを責めるように尋ねてきたときに現れる。
30 分ペアリングしてコードを説明するより、この ADR を渡して、そのモジュールを作る間に下した決定について説明できるようになる。
あなたのためではなく、あなたの同僚のためのもの
ADR には、「この機能は feature-#3128 の実装です」という 1 行の説明よりも長い内容を書くべき。
同僚が、なぜこの機能を別の方法ではなくこの方法で作ったのかを理解する助けになる、もう少し長い説明の形式。
(ADR 内では「検討した代替案」「長所と短所」などで表現)
あなたには簡単なことでも、同僚には複雑かもしれない。
少し時間を取って、決定を下すときに考えた過程を書き残しておけば、チームメンバーがあなたの頭の中に入る機会を与えられる。
ADR を書けば、「Decision Socialization(意思決定の社会化)」が可能になる。
そうすることで、個別に決定を下すのではなく、チームが保守に責任を持つ決定を下せるようになる。
プルリクエストを上げる前に ADR を書けば、それをレビューするチームから、より良い PR レビューを受けられる。
あなたのためではなく、未来の同僚のためのもの
ADR は、あなたがどれほど賢いかを見せるためのものでも、人々があなたの作ったアーキテクチャを見て戸惑うためのものでもない。
ADR は、新しいチームメンバーが入ってきたときに、現在のコードベースと、そのコードベースがこれまでどのように発展してきたのかを理解する助けになる。
チームが拡大し成長するにつれて、チームメンバー間のコミュニケーション経路は増えていく。
このように下した決定を書き残しておけば、チームの成長に伴って新しく加わる人たちとの意思疎通にも役立つ。
最良のシナリオは、チームメンバーが新しい ADR を書いて、あなたが以前に下した決定を置き換え、将来はあなたが同僚から学べるようになること。
「もっと多くの ADR を書きましょう。チームが大きくなり、コードベースが複雑になるほど、ADR は未来の私たち、今のチームメンバー、そして未来のチームメンバーを助ける良い方法です。」
3件のコメント
電子政府の事例の中でも有名なGov.UKには、自分たちのAWSクラウドアーキテクチャに関するADRを整理したリポジトリもあります。
https://github.com/alphagov/govuk-aws/…
とても参考になりました。
ADR の事例
CSS フレームワークの決定
https://github.com/joelparkerhenderson/architecture_decision_record/…
前提 : モダンで高速、かつレスポンシブな Web アプリを作りたいので、jQuery は使いたくない
制約 : jQuery を使わなくてよいフレームワーク
検討 : 何も使わない案、または Bootstrap/Bulma/Foundation/Materialize/Semantic UI の中から、Bulma と Semantic UI を重点的に検討
Monorepo vs Multirepo
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ SCM として git を使っているため、monorepo vs polyrepo vs hybrid を決めなければならない
→ 組織/チーム/プロジェクトが小さく、迅速なイテレーションが必要なときは Monorepo
→ 組織/チーム/プロジェクトが大きく、安定性が重要なときは Polyrepo
プログラミング言語の決定
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ フロントエンドは TypeScript
→ バックエンドは Rust
→ フロントエンドは一般的でありながら、迅速に開発・デプロイ・反復できる必要がある。レガシー互換は不要
→ バックエンドは一般的であることより少し上を目指す。品質、安定性、セキュリティへの配慮が必要。ほぼリアルタイム級が必要(GC によって停止してはいけない)。関数型プログラミング / 並列処理およびマルチコア処理、メモリ安全性も重要
制約 : 主要クラウドサービスのサーバーレス(Amazon Lamba)で必ず実行可能でなければならない
検討 : C/C++/Clojure/Elixir/Erlang/Elm/Flow/Go/Haskell/Java/Javascript/Kotlin/Python/Ruby/Rust/TypeScript
議論 :
→ C : 安全性が低いため除外; Rust のほうが大半のことをよりうまくできる
→ C++ : 雑然としているため除外; Rust のほうが大半のことをよりうまくできる
→ Clojure : 優れたモデリング; Lisp に最も近い; JVM 上の優れたランタイム
→ Elixir : デプロイと並行性に優れたランタイム; 優れた開発者体験; 比較的小さなエコシステム
→ Erlang : デプロイと並行性に優れたランタイム; やや挑戦的な開発者体験; 比較的小さなエコシステム
→ Elm : 将来有望; IBM が良い事例を共有中; 小さなエコシステム
→ Flow : JS の興味深い改善; しかし開発者は離れつつある
→ Go : 優れた開発者体験; 優れた並行性; 言語を奇妙にする悪い決定がいくつかあった
→ Haskell : 最高の関数型言語; 小さな開発者コミュニティ; 本番での成功事例があまり多くない
→ Java : 最高のランタイム; 優れたエコシステム; 可もなく不可もない開発者体験
→ JavaScript : 最も人気のある言語; 最も広いエコシステム
→ Kotlin : Java の多くを改善; JetBrains による優れた支援; Java to Kotlin のさまざまな成功事例
→ Python : システム管理分野で最も人気のある言語; 良い分析ツール; 良い Web フレームワーク; Google が Go を選んだことで捨てられた
→ Ruby : 最高の開発者体験; 最高の Web フレームワーク; 優れたコミュニティ; 非常に遅い; パッケージ化しにくい
→ Rust : 最高の新しい言語; Zero-cost abstractions(抽象化しても速度が低下しない)を強調; 並行性を強調; 比較的小さなエコシステム; 一部のコンパイラ最適化には限界がある(メモリ直接アクセスは unsafe である必要がある、など)
→ TypeScript: JavaScript に Type を追加; 優れた Transpiler; 開発者は徐々に JS から TS へ移行中; Microsoft の強力な支援
VM ベースは選ばないことにした(複雑性が増すため)
最速のランタイムを求めるなら JS と C を選ぶ
最高に近い速度のランタイムを求めるなら TypeScript と Rust を選ぶ
もし VM と Web フレームワークを選んでいたなら
→ Closer と Luminous
→ Java と Spring
→ Elixir と Phoenix