開発者の開発者による開発者のためのAgileドキュメンテーション

開発者であれば避けては通れないドキュメンテーション。
しかし多くの開発者が嫌がっているドキュメンテーション。

今回はアジャイル型開発（以下、アジャイル）のプロジェクト・チーム開発者における**最適なドキュメンテーション**について考察したいと思います。

## アジャイルとドキュメント
### ドキュメントは書かなくて良い？
日本においてアジャイルはゆっくりだが確実に浸透しています。
7年間アジャイルをしていた私としては嬉しく思う反面、世間には誤った認識が広がっているのもまた事実です。以下は[アジャイル勘違い集](http://objectclub.jp/technicaldoc/xp/agile_misunderstanding)の抜粋です。

> Q. ドキュメントを書かない？
> もちろんアジャイルプロセスでもドキュメントは書きます。ただ優先順位が異なるだけです。 
> ... 
> 最小限の文書化で最大限の効果を狙う、必要にして十分なドキュメント。そうしたドキュメントは一朝一夕に書けるものではありません。 
― [ドキュメントを書かない？｜アジャイル勘違い集](http://objectclub.jp/technicaldoc/xp/agile_misunderstanding#q3)

上記の通り、アジャイルではドキュメントを書かなくていいわけではありません。
しかし優先度を見極めて必要最小限のドキュメンテーションを行う、ということはとても難しいものです。


### ドキュメントはどこまで必要か？
一重にドキュメントといっても様々な種類があります。

- システム全体を俯瞰する
    - システム構成図
    - 業務フロー
    - ...
- アプリケーションの機能を示す
    - 画面遷移図
    - データベース設計
    - ...
- アプリケーションの実装詳細を示す
    - クラス図
    - ユースケース図
    - ...
- 運用
    - 作業手順書 （リリース/定常作業）
    - ...

ウォーターフォール型開発においては、要件を満たす仕様/実装であるかを確認するために様々な角度の設計図を書き起こします。これは開発フローの性質上、必須な資料です。

しかしアジャイルではここまでのドキュメンテーションは必要ないように思えます。
（これはウォーターフォールを否定しているわけではありません。）

### アジャイルでドキュメントと向き合う
アジャイルでドキュメントと向き合うときに念頭に置いておく必要がある考えがあります。

> Agile methods are not opposed to documentation, only to valueless documentation.
> (アジャイルの手法はドキュメントを書くこと全体に反対を示しているのでなく、価値のないドキュメントのみに反対を示しているのだ)
> ― [Documenting Architecture Decisions｜Michael Nygard Blog](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)

アジャイルでは **ソースコードを最重要ドキュメント**と位置づけて、価値のないドキュメントを排除することを目的としていると言えます。

ここでいう"価値のないドキュメント"といっているのは「最終成果物として価値のない資料」と言っているのではなく、アジャイル開発フローを進める上で価値のない資料であることを意味しています。ですので、ウォーターフォールと同様、システムの引き継ぎ時に必要に応じて作成する必要はあるかもしれません。

つまりは変化を許容するアジャイルにとってソースコードと同等の設計書を書くことは二重管理となり、開発速度を落とすことにつながることを意味しています。

## 開発を加速させるドキュメンテーション
ここからは必要最小限のドキュメンテーションで開発を加速させ最大限の成果を得るためにはどのドキュメントに注意を払うべきかについて考えていきます。

まずは私が最上位の優先度で、かつ、繊細に扱わないといけないと認識しているドキュメントです。

```
# Project Repository
 ├ doc/adr
 │  └ Architectural Decision Records (ADR)
 ├ src
 │  ├ Source Code
 │  └ Source Code Document
 └ README

# Engineer-ing
 ├ Pull Request (Merge Request)
 └ Commit Log
```

一つ一つのドキュメントに関して紹介していきます。

#### ■Architectural Decision Records（ADR）
プロジェクトやチームにおける**アーキテクチャの意思決定の記録**を残すためのドキュメントです。
（[Documenting Architecture Decisions｜Michael Nygard Blog](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions) にて詳細に書かれています）

##### なぜこの文書が必要か?
変化を許容するアジャイルにおいて、意思決定の経緯は従来より重要になります。

プロジェクトの途中で様々なアーキテクチャやライブラリが変更されるといったことが起こりえる中で「なぜこの技術が採用されたか」などの決定経緯が追跡できなくなることはしばしば発生します。また追跡できない事態が続くことにより変化するための意思決定を避けたり、過去の経緯を無視して新たなものを採用する事態となります。

これらを回避するためには 意思決定の経緯をソースコードと紐づけて記録しておく必要があります。

##### どのような内容を書く?
以下の項目に沿って意思決定の記録を行います。
なお、ADRの具体例については以下Repositoryが参考になります。

- [arachne-framework｜GitHub](https://github.com/arachne-framework/architecture)
- [adr-tools｜GitHub](https://github.com/npryce/adr-tools/tree/master/doc/adr)

###### Title （タイトル）
ADRの概略を書きます。

###### Context （コンテキスト）
コンテキストでは以下の事柄をいずれの背景に対しても中立な立場で、かつ、事実に基づき記載します。

- この決定を必要とする理由
- プロジェクトを取り巻く技術・社会・政治的な背景
- とりえる選択肢と概要 
- etc.

###### Decision （決定事項）
アーキテクチャに関するプロジェクトの意思・決定事項を記載します。

- 採用する技術や設計 （言語・ライブラリ・フレームワーク など）
- 決定に至った理由や背景
- 採用しなかった技術や設計に対する理由
- etc.

###### Status （ステータス）
ADRの意思決定がどの状態かを記載します。以下の3種類から選択します。

|ラベル|説明|
|:------|:--------|
|proposed|**提案中** :同意がなされていない状態|
|accepted|**受理** :プロジェクト内で合意がなされている状態|
|deprecated|**廃止** :本ADRの意思決定を変更あるいは取り消されている状態|

###### Consequences （結果）
ADRを適用した後のコンテキストについて記載します。
良かった点だけでなく悪かった点を含めリストアップすることが望まれます。


#### ■README
言わずと知れた `README.md` です。

##### なぜこの文書が必要か?
すでに多くの人が書いているドキュメントですが重要なドキュメントの一つです。
適切なアナウンスをすることでより重要なドキュメントへ導くことができます。

- [設計図共有サイト](https://nyakki-yossi.hatenablog.com/entry/2018/06/05/045938)でデフォルトで表示をしてくれるため開発者の目に留まりやすい
- 開発者の目に留まりやすいため、すべてのドキュメントの起点としての役割を据えられる
    - 結果、ドキュメントの分散を抑えられる

##### どのような内容を書く?
数多の記事で紹介されているため、一つ一つの項目を取り上げることは割愛します。

- [わかりやすいREADME.mdを書く｜SOTA](https://deeeet.com/writing/2014/07/31/readme/)
- [わかりやすい README 駆動開発｜Qiita](https://qiita.com/b4b4r07/items/c80d53db9a0fd59086ec)

以下はよくあるREADMEの一例です。

```
Project Title
--------------------------------------------
## Description（概要）

## Requirements（前提となる開発環境）
 - 言語
 - フレームワーク など

## Usage（使い方）
 - 開発環境の構築手順
 - アプリケーションの起動方法 など

## License（ライセンス）
```

#### ■Pull Request / Merge Request
こちらもおなじみのPull Request（サイトによってはMerge Request）です。

##### なぜこの文書が必要か?
「そもそもこれ文書じゃなくね？」と言われるかもしれませんが、以下理由で開発者にとっては繊細に扱うべき文書だと考えます。

- 立派なレビュー依頼票
- VCSの変更管理の記録

ソースコードを最重要ドキュメントと捉えたとき、その変更に関わる

- なぜこの変更が必要なのか？ （Why）
- どのような実装をしたのか？ （What）
- チェック観点
- 影響範囲

をレビュアーに正しく伝えるための文書にあたりますので当然重要な文書と言えます。

##### どのような内容を書く?
まず内容を書き始める前に自分の切り出した作業単位（branch）が以下に沿っているかを確認する必要があります。

> 1.　小さくまとめる
> 小さく、焦点を絞ったプルリクエストは、承認される可能性が非常に高い。 ... 
> 経験上、プルリクエストの大きさに対してレビュー時間は指数関数的に長くなってしまう。
> 2.　1つの事だけやる
> [単一責任の原則](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E5%8D%98%E4%B8%80%E8%B2%AC%E4%BB%BB%E5%8E%9F%E5%89%87/)で、1つのクラスは1つの責任(役割)のみを持つとされているように、1つのプルリクエストは1つのテーマのみを扱うべきだ。
> ー [より良いプルリクエストのための10のヒント｜Yakst](https://yakst.com/ja/posts/1625)

また 心構えとして[なぜあなたのPull Requestは読まれないのか](https://qiita.com/SpicyCoffee/items/b580afe3a86fabf61b1c)にも目を通しておくことをオススメします。その上でPull Requestに内容を埋めていきます。

以下はよくあるPull Requestの一例です。

```md
Pull Request Title
--------------------------------------------
## What(このPull Requestは何か?)

## Why(なぜこのPull Requestが必要か?)

## Impacted Areas in Application(影響範囲)

## Todo / Checklist
 - [ ] xxxxxx

## Refs
 - [#100]()
```

最後に忘れずにPull Requestをテンプレート化しましょう。

- [GitHubのIssue・Pull Requestのテンプレート機能を使おう｜Qiita](https://qiita.com/nyamogera/items/3fe6985b45fbd5377184)

#### ■コミットログ
こちらもおなじみのVCSにコミットする際のログです。

##### なぜこの文書が必要か?
ソースコードをコミットという意味のある作業単位にまとめ、ログをつけることは以下に役立ちます。

- ソースコードの変更詳細をレビュアーに伝えられる
- コミットのラベリングはコミットを切り戻す場合の検索性を高めてくれる

また[コミットメッセージの書き方](https://www.clear-code.com/blog/2012/2/21.html)も合わせて目を通しておくと良いでしょう。
どのコミットもすべて同じコミットメッセージという人がたまにいますが言語道断です。

##### どのような内容を書く?
原則としては「１コミットは可能な限り細かい作業単位/粒度」にすることです。
加えて以下の工夫をすることでより良いコミットにすることができます。

###### コミット種別
以前に[コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話](https://qiita.com/numanomanu/items/45dd285b286a1f7280ed)を読んで大変感銘を受けましたが、今回私がおすすめしたいのが以下の**Emojiプレフィックス**です。

Emojiコミットの良い点としては、文字に比べて絵の方が直感的に変更内容を伝えられるという点です。
<img width="650" src="https://qiita-image-store.s3.amazonaws.com/0/93055/91ac0ae6-f28e-4e8b-054a-adb54f7f7b9e.png"/>

|Emoji|コミット種別|説明|
|:---:|:---|:---|
|:sparkles:|New Feature|新規機能の追加|
|:recycle:|Refactoring|リファクタリング|
|:books:|Documentation|ドキュメンテーションの追加/更新|
|:art:|Cosmetic|デザインの追加/更新|
|:wastebasket:|Removal|ファイルや不要なコードの削除|
|...|...|...|

- [commit-message-emoji | GitHub](https://github.com/dannyfritz/commit-message-emoji)

###### コミットメッセージ本文
コミットメッセージ本文については以下が参考になります。

- [Gitのコミットメッセージの書き方｜Qiita](https://qiita.com/itosho/items/9565c6ad2ffc24c09364)
- [GitHub English Challenge Cheat Sheet
｜Qiita](https://qiita.com/kawasima/items/feac49a299213e2c8ba6)


## まとめ
- アジャイルにおけるドキュメンテーションは軽視されがちだが、的を絞って注力することで最大の成果を得る武器になる
    - ADRを有効活用することで過去・現在・未来に渡って意思を伝えることができる
- Pull Requestやコミットログなど普段何気なく書いているドキュメンテーションにも気をつけることで開発速度を加速されるファクターに変化させられる

## 参考文献
**アジャイル**

- [アジャイルソフトウェア開発宣言｜Agile Manifesto](https://agilemanifesto.org/iso/ja/manifesto.html)
- [アジャイル勘違い集｜objectclub](http://objectclub.jp/technicaldoc/xp/agile_misunderstanding)

**Docsガイドライン**

- [Write the Docs](https://www.writethedocs.org/guide/)

**ADR** ―  [@kawasima](https://twitter.com/kawasima)さんから教えていただきました。ありがとうございます。

- [Architectural Decision | Wikipedia](https://en.wikipedia.org/wiki/Architectural_decision)
- [Documenting Architecture Decisions｜Michael Nygard Blog](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
- [アーキテクチャの意思決定を記録する Lightweight Architecture Decision Records について｜Tbpgr Blog](http://tbpgr.hatenablog.com/entry/2017/02/22/080000)

**Pull Request / Merge Request**

- https://gist.github.com/Lordnibbler/11002759
- https://embeddedartistry.com/blog/2017/8/4/a-github-pull-request-template-for-your-projects

**コミットログ**

- [【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話 | Qiita](https://qiita.com/numanomanu/items/45dd285b286a1f7280ed)
- [commit-message-emoji | GitHub](https://github.com/dannyfritz/commit-message-emoji)