アーキテクチャの「なぜ？」を記録する！ADRってなんぞや？


 5月のThoughtWorksの[Technology Radar](https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records)でも`ADOPT`されたADRという手法について、面白かったので、ざっくり自分なりに調べたメモです。

[Technology Radar](https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records)では以下のように述べられています。

>多くのドキュメントは、読みやすいコードとテストに置き換えることができます。しかし、進化的アーキテクチャでは、将来のチームメンバーの利益と外部の監督のために、特定の設計上の決定を記録することが重要です。Lightweight Architecture Decision Recordsは、重要なアーキテクチャー決定を、そのコンテキストおよび結果と共に取り込むための技法です。これらの詳細は、WikiやWebサイトではなくソース管理に格納することをお勧めします。そうすれば、コードと同期したままのレコードを提供できるからです。ほとんどのプロジェクトでは、この手法を使いたくない理由はないでしょう。

## ADRって？
目の前にコードはあるけども、それがなぜそう設計されたのかは謎:confounded:
その背景にあった理由、決定への過程がわからないまま、追加や変更の意思決定を行わなければならない:confounded:
そういったことの積み重ねで、新たな変更や追加、意思決定が難しく、プロジェクトの闇が深くなってしまう:confounded:
といったことは、よくあるのではないでしょうか。

この原因のひとつとして、アーキテクチャがなぜそうなっているかなどは記録に残らない(残りにくい)ということがあるからと言えると思います。

私が思うに、ADRは、そういったアーキテクチャの「なぜ」を残して、将来のチームメンバーや、プロジェクトの意思決定に役立ててはっぴーになっていこう！というドキュメントです。

また、こういった決定の過程は、とても大切なナレッジなので、固有のプロジェクトに限らず、組織全体や、開発者みんなが参考にしていけるドキュメントになる可能性があるのではないかと思います:sparkles:

## 役立つドキュメントにするために
ただ作成するだけ、あるいは、更新されていなくて、情報も古いドキュメントでは、チームや、プロジェクトやメンバーの役に立ちません。コストもかかるし、つらみが増してしまうでしょう。
ADRは、1つのファイルを、小さくシンプルにして、ソースコードと一緒に管理します。こうすることで、読んだり、更新したり、書いたりしやすくして、きちんと役立つドキュメントを目指します。

## ADRの書き方
ADRでは、アーキテクチャ上重要な決定(Architecture decision)を残します。
ADRファイルは、概ね下記のようなシンプルなセクションから成り立ちます:

* タイトル(Title)
* コンテキスト(Context)
* 決定(Decision)
* ステータス(Status)
* 結果(Consequences)


以下、セクションごとの概要を簡単にみてみます。
個人的には、下記の要素を参考にしながら、プロジェクトに有益な形のドキュメント形式にしていくのが良いのではないかと思いました:thinking:

### タイトル(Title)
決定のタイトルを簡潔に記します。
(英語の場合、短い名詞句で記すようですが、日本のプロジェクトでは、簡潔に決定の名前を記述することができればよいのではないかと思いました。)

### コンテキスト(Context)
多くの場合、アーキテクチャにおける決定は、さまざまな力関係がひっぱりあっており、それらのトレードオフにあるのではないでしょうか。(組織の状況、ビジネスの優先事項、技術的なものなど)
このセクションには、ひっぱりあっている力と、その関係を記します。
コンテキストは、中立的に、事実だけを書くようにします。

### 決定(Decision)
これらの力に対する対応について記します。「私達は、○○します。...」

### ステータス(Status)
* 合意していない場合は「提案」
* 合意された場合は「承認」

後にADRを決定を変更または取り消した場合、置き換えられた決定を参照して「非推奨」または「置き換え」とマークされることがあります。
  
### 結果(Consequences)
決定を適用した後の結果のコンテキストについて記します。
決定がもたらした「プラス」の結果、「マイナス」の結果、「中立の結果」問わず、すべての結果は、ここに記されます。
「プラス」と「マイナス」という観点から、ただ決定を説明するのではなく、"YではなくXをする必要がある。とするとよりよい「結果」になるでしょう。

### その他

#### ADRファイルの命名規則
* ADRには、順次番号を付けるとよいでしょう。(数字は再利用されない。)
* 拡張子は、markdown形式にするとよいでしょう。(gitはフォーマット表示してくれるので、読みやく共有しやすい)

#### 新しいADRが以前のADRの代わりになることがある
以前のADRを置き換えるか無効にする「決定」がなされた場合は、新しいADRを作成します。
決定が変更になった場合は、古いものをそのまま手元に置いておきますが、「取り消された」ものとしてマークします。(どういった決定であったかを知ることは大事ですが、取り消された決定は、もはや決定ではありません。）

#### 開発者とプロジェクト関係者が、ADRを参照できるようにする
時間が経ってチーム構成が変わったとしても、開発者とプロジェクト関係者は、ADRを参照できるようにします。「なぜその決定がなされたのか」は、過去・未来の誰でも見れます。そうすることで、「何を考えてこうしたの？」と悩む人はいなくなるでしょう。

#### 良いADRの特徴：
* ポイントインタイム(Point in Time)
決定が作成された時を特定できる。

* 合理性(Rationality)
その決定が作成された理由を説明する。

* イミュータブルレコード(Immutable record)
以前に公表されたADRでなされた決定は変更されるべきではない。

* 特異性(Specificity)
各ADRは単一の決定についてであるべき。

## ツールとテンプレートの紹介
最後に、[adr.github.io](https://adr.github.io)から引用して、ADRのツールと、テンプレートを紹介します。

### ツール
* [ADMentor](https://github.com/IFS-HSR/ADMentor) Architectural Decision Modeling アドイン for [Sparx Enterprise Architect](https://www.sparxsystems.de/uml/neweditions/)
* [adr-tools](https://github.com/npryce/adr-tools) - [Nygard format](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)のフォーマットで、ADRを管理するためのbashスプリクト
  [実際にこのツールで書かれたADRの例がリポジトリにあります](https://github.com/npryce/adr-tools/blob/master/doc/adr/0002-implement-as-shell-scripts.md)
    - Javaで書かれたもの: [adr-j](https://github.com/adoble/adr-j)
    - C#で書かれたもの: [adr-cli](https://github.com/GingerTommy/adr-cli)
    - Goで書かれたもの: [adr](https://github.com/marouni/adr)
* ADRツールをインストールするためのAnsibleスクリプト: [ansible-adr-tools](https://github.com/escalate/ansible-adr-tools)

* PHPベースのCLIのADRツール: [phpadr](https://github.com/globtec/phpadr)    
* Powershellモジュール: [adr-ps](https://github.com/rdagumampan/adr-ps)
* もう一つのPowershellモジュール: [ArchitectureDecisionRecords](https://github.com/ajoberstar/ArchitectureDecisionRecords)
* [adr-viewer](https://github.com/mrwilson/adr-viewer) - ローカルWebサーバーまたは静的コンテンツとして、WebページでADRを見られるようにするPythonアプリケーション
* [ArchUnit](https://github.com/TNG/ArchUnit) - アーキテクチャのためのユニットテスト
* [docToolchain](https://doctoolchain.github.io/docToolchain/) - ソフトウェアアーキテクチャのための[docs-as-code](http://www.writethedocs.org/guide/docs-as-code/) アプローチと多少の自動化の実装

* [Structurizr](https://www.structurizr.com/) - [C4 model](https://c4model.com/)を使用してソフトウェアアーキテクチャを視覚化、文書化、および探索するのに役立つツールのコレクション

### テンプレート
  * [ADR template by Michael Nygard](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_by_michael_nygard.md)

  * [ADR template by Jeff Tyree and Art Akerman](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_by_jeff_tyree_and_art_akerman.md)

  * [ADR template for Alexandrian pattern](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_for_alexandrian_pattern.md)

  * [ADR template for business case](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_for_business_case.md)
  * [ADR template MADR](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_madr.md)
  * [ADR template using Planguage](https://github.com/joelparkerhenderson/architecture_decision_record/blob/master/adr_template_using_planguage.md)

## 参考
* [Documenting Architecture Decisions Relevance](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
* [adr.github.io](https://adr.github.io)
* [Architecture decision record (ADR)](https://github.com/joelparkerhenderson/architecture_decision_record)
* [Lightweight Architecture Decision Records Technology Radar ThoughtWorks](https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records)