【読書メモ】アジャイル開発とスクラム 顧客・技術・経営をつなぐ協調的ソフトウェア開発マネジメント

生産性の改善とかでよく使われるスクラムに関する本を読んだので内容まとめました。

[アジャイル開発とスクラム~顧客・技術・経営をつなぐ協調的ソフトウェア開発マネジメント | 平鍋 健児, 野中 郁次郎 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA%E3%81%A8%E3%82%B9%E3%82%AF%E3%83%A9%E3%83%A0-%E9%A1%A7%E5%AE%A2%E3%83%BB%E6%8A%80%E8%A1%93%E3%83%BB%E7%B5%8C%E5%96%B6%E3%82%92%E3%81%A4%E3%81%AA%E3%81%90%E5%8D%94%E8%AA%BF%E7%9A%84%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%83%9E%E3%83%8D%E3%82%B8%E3%83%A1%E3%83%B3%E3%83%88-%E5%B9%B3%E9%8D%8B-%E5%81%A5%E5%85%90/dp/4798129704/ref=sr_1_2?ie=UTF8&qid=1510547074&sr=8-2&keywords=%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB)

本書では一部でスクラムの根元のアジャイルの概念を説明した上で、アジャイルを実現するスクラムという開発手法について説明しています。第二部でリクルートなどの事例があげられてますが、今回はそっちはまとめてないです。

## 1章 アジャイルとは

- 分析、設計、実装、テストを短い単位（1週間から1ヶ月）で繰り返して開発する手順

### アジャイル開発のメリット

- 動くものが早い段階で見えることによるリスク軽減
- 仕様の変更への柔軟な対応
- 顧客やユーザからのフィードバック

### 価値観が重要

- アジャイル宣言に基づいていればアジャイル開発になる
    - [アジャイルソフトウェア開発宣言](http://agilemanifesto.org/iso/ja/manifesto.html)
    - プロセスより個人との対話に価値がある
    - ドキュメントより動くソフトウェアに価値がある
    - 計画を遵守するより仕様の変化への柔軟な対応に価値がある
    - 顧客との協調にこそ価値がある

## 2章 なぜアジャイルか

### 従来の手法の問題

- 従来の流れ
    - ビジネルが市場分析ｰ>ITへ発注
    - ITがビジネルへ納品ｰ>市場へリリース
- 問題点
    - ビジネスとITでゴールがずれている
        - IT:納品することがゴール
        - ビジネス:システムへの投資で最大の効果を上げることがゴール
            - 足の引っ張り合い
    - 市場へリリースするまでに時間がかかりすぎる（半年から3年）
        - 時間がかかりすぎると市場が変化してしまい、市場分析した当初の状況が当てにならない（要求の劣化）

### アジャイルが目指すもの

- 上記の問題の解消
    - ゴールがずれているｰ>ITのゴールもビジネスの効果を上げることにして統一をする
        - 足を引っ張り合って要らない機能を作ったり、仕様変更で揉めたりしなくなる
            - 開発効率がアップ
    - 早期リリースによる早期フィードバック
        - 短い単位でリリースを行うため、早い段階で顧客やユーザのフィードバックが得られる
            - フィードバックによる市場の変化を捉え、機能の優先度を柔軟に変更できる
                - 無駄な機能への投資がなくなる
                - 最大限の効果が得られる機能へ注力できる
                - 要求の劣化対策

## 3章 スクラムとは

### スクラムとは

- アジャイル開発の一つ
- 実測と反復による知識を重視する（経験的プロセス）
    - WFは予見的プロセス

### スクラムのプロセス

1. プロダクトバックログの作成
    - 順位付けられた機能リスト
    - 顧客目線で書く（ユーザーストーリ）
        - 機能だけでなく目的を明確にする
2. スプリント計画を実行し、スプリントバックログを作成する
    - スプリント計画とは
        - プロダクトバックログから1スプリントでやる分（スプリントバックログ）を抜き出す
            - 抜き出すのは順位に基づく
        - バックログの機能について、チーム全体へ説明して理解をしてもらうのもここで行う
        - 開発チームはスプリントバックログの内容を詳細化（タスク化）して計画を立てる
        - 各バックログの見積もりやタスクの見積もりもここで行う
3. スプリントを実行する
    - スプリントとは？
        - 1から4週間くらいの決まった短い開発期間
        - スプリント期間内でスプリントバックログの機能を実装し、デモできる環境（インクリメント）を作ることが目的となる
        - スプリント期間内は毎日デイリースクラム（朝回）を実行し、チームの状況を共有する
            - デイリースクラムとは？
                - いわゆる朝回
                - 各メンバーの昨日やったこと、今日やること、直面している障害について報告し合う
                    - 障害についてはスクラムマスターが解決に尽力する
4. スプリントが終了したらインクリメントをデモして、関係者全体でレビューを行う
5. レビューまで終わったらレトロスペクティブを行う
    - レトロスペクティブとは？
        - いわゆる振り返り
        - スプリントでうまく行ったこと、行かなかったこと、次どうすればうまく行くかなどを話す
        - チームの学習、改善が目的であり正直な意見を出し合うことが大事
        - 後述するKPTなどを使う

### スクラムにおける3つの役割

#### プロダクトオーナー

- 機能開発による投資対効果（ROI）を最大にすることに責任を持つ役割
- バックログの追加、削除、順位付けもオーナーの責任
- バックログの内容を開発チームへ説明するのもオーナーの役割
- 合議制にせず1人で行う

#### 開発チーム

- バックログに入っている項目を完了とする役割
- 開発の主体で、開発のやり方などの決定権も持つ

#### スクラムマスター

- スクラム全体が自律的に協働できるように場作りをする役割。ファシリテーター的なの
- チームの支援役（サーヴァントリーダー）
    - 割り込みの防止
    - 障害の排除
    - etc
- 開発のやり方を決めるのは開発チームで行う

## 4章 アジャイル開発の活動（プラクティス）

プラクティス=実施活動（具体的な活動）

### ユーザーストーリ

- ユーザの言葉で機能の説明を行ったもの
	- 要求仕様書的な役割
- 紙のカードとかで管理するのが望ましい
	- 詳細までカードに記述する必要はない
		- 詳細については対話を通じて理解を共有する（スクラム宣言）
	- カードに記載する内容は簡潔に
		- フォーマット例
			- ○○として☓☓が欲しい。なぜなら、△△だから
				- ○○ ユーザの役割
				- ☓☓ 機能
				- △△ 価値、目的
			- 対象のユーザと提供する価値や目的がわかることが大事
				- UIデザインや機能実装を考える上でのベース
- バックログの項目として利用する
	- 見積もりには後述のプランニングポーカーなどを使う

### プランニングポーカー

- バックログ項目を見積もる手法
- 複数人の意見を素早くまとめることができる
	- 見積もりの精度の向上
	- チーム全員の納得感
- 専用のカードがある
	- 自作も可

#### プランニングポーカーの使い方

1. ベースラインを決める
	- チーム全員がよく知っているバックログ項目を1つ決める
	- 決めたらその項目に基準値を適当に仮決めする（例えば２とか）
		- ここで選ぶ項目はあまり大きすぎないのを選ぶ
2. 見積もりするバックログ項目を選ぶ
	- 1.のベースラインと比較しつつ、どれくらい掛かりそうか見積もる
		- 例えば、ベースの2倍掛かりそうならベースの基準値*2と見積もる
	- 開発チームのメンバー全員でやる
3. カードを場に出す
	- 全員一致なら終了
	- 一致しなければ次へ
4. 見解発表
	- 最大値、最小値の見積もりをした人に理由を話してもらう
		- 短時間で
5. 再度カード提出
	- 一致すれば終了
	- 一致しなければ4.へ
		- 3回やっても一致しなければ〆る
			- 決め方は最大値もしくは平均値など

### デイリースクラム（朝回）

- 開発チームの情報共有のためのミーティング
- 毎日決まった時間に行う
- タスクカンバンやバーンダウンチャートなど、プロジェクトの状況を可視化するものの近くで行うと効果的
	- チームの状況の共有、アップデート
- 3つのことを話す。短く簡潔に
	- 昨日やったこと
	- 今日やること
	- 障害になっていること
- チーム内の各自の仕事に透明性をもたせることが大事
	- 一人だけで仕事しているのではなく、一体感を持って仕事できるような場を作る
		- 心理的安全性にもつながるかな
- 進捗報告会ではないので注意
- 大きい問題については別途時間を作ってそこでやる
- 部外者の発言は制限する
	- 適当なこと言いかねないので

### 振り返り（レトロスペクティブ）

- 良かったこと、悪かったこと、今後改善したいことなどを本音で話し合う機会
	- チームの一体感が必要かも
- PDCAのCAに当たる部分
- スプリントにおける「気付きを共有する」ことと「今後の活動に活かす」ことが主な目的
	- 責任追及が目的になってはいけない
		- ファシリテーターの頑張りどころ
	- 課題リストを作るのではない
- KeepProblemTime（ケプト）
	- 良かったこと（Keep）、問題だったこと（Problem）、試したいこと・問題の解決策（Try）についてまとてる手法
	- ホワイトボードなどを3つの領域に分けて、Keepｰ>Problemｰ>Tryの順に意見を出していく
		- Keep___ |          Try
		- Problem        |
		- Keepを先に話すことでポジティブに話が開始できる
			- 雰囲気が良くなる
	- 話す項目はチームに関係しそうならなんでもよし
		- 製品について、作り方のプロセス、顧客との関係、日々のコミュニケーション、職場環境、etc
	- 改善に仕方について自分たちで考える（自律的）であることが大事

### タスクかんばん

- チームの作業タスクをすべてカード（付箋）に書き出し、壁に貼って可視化したもの
	- タスクは進捗状況ごとに用意した区画に貼っていく
		- 区画についてはチームに合わせて調整
			- 例）Todoｰ>Doingｰ>Done
			- ドキュメント化が必須ならDocumentation、レビュー待ちを表現したいならWaitForReviewとか追加するといいかも
- 手順
	1. スプリント計画時にすべてのタスクを洗い出す
		- 漏れてたらどうするんだろ？
	2. 1.をカードにしてTodo区画に貼る
	3. 朝会で各自がTodoからやることを決める
		- 各自が自主的にタスクを取る（サインアップ）することが大事
	4. 3.をDoing区画に移動
	5. Doingのタスクが完了したらDoneへ
- 効果
	- チームの状況がひと目でわかる
- 注意
	- WIPを作りすぎない
		- 仕掛品を貯めるのではなく、先に完成していくことが大事
		- 貯まるようなら、何がボトルネックになっているかを特定して解決する
	- タスクを大きくしすぎない
		- 2時間から3時間で終わるくらいが望ましい
		- 大きすぎるとタスクが動かなくなる
			- 状況が見えづらい
			- 達成感への影響
				- タスクを動かす行為自体が達成感につながるみたい
- よくある質問
	- リモートとやる方法
		- Webのツールを使う
			- といっても、最初のキックオフや数スプリントは1箇所で行い、慣れさせたほうが良い
			- Webツールの画面を印刷して壁に貼るのもあり
		- Webカメラの常時接続
			- カメラの前にかんばんやバーンダウンチャートをおいておけばそのまま共有できる
			- 雰囲気の共有もできる
			- 朝回、ふりかえりもできる

### バーンダウンチャート

- スプリント内での残作業量を確認し、現在の進捗を知るためのツール
	- 毎日の朝回後などに記録していく
- 想定している作業量の減り方（理想線・計画線）を始めに引き、毎日の実績を残量線として追記していく
	- 理想線と残量線が離れ始める＝問題が生じているｰ>スクラムマスターが何らかのアクションを取る（リスケや調整等）
- 各タスクの作業量の単位は理想時間で行う
	- 割り込み無しで考えた場合の時間
- TIPS：進捗の聞き方
	- 完了するまであと何ポイント必要か？
		- 何％残っているかはNG
			- 想定より作業量が増えた場合に言いづらい
				- 見積もりに誤りがあった場合に正直に報告して、実際の状況が見える状態を維持しないと意味がない
- TIPS：直前のスプリントで完了できたポイント数（ベロシティ・開発速度）を次のスプリントの目安にする
	- はじめは安定しないが、繰り返すことで正確な見積もりができるようになっていく

### ペアプログラミング

- 2人1組でプログラミングする方法
	- 画面共有などを使えばリモートでも可能
	- シリコンバレーだとこっちが主流みたい
- メリット
	- リスク対策
		- ミスが起こりやすい作業はペアで行うことが望ましい
			- パイロットのフライトやスキューバダイビングとかと同じ
	- リアルタイムレビュー
	- 知識・考えの共有
		- より良いアイデア、設計になる
	- 会話を通じてのチームの一体感の増強
	- コードの属人化の防止
- やり方
	- キーボードを打つドライバと、一歩下がって助言、質問を投げるナビゲータに分かれて行う
		- 15分位で交代する
- よくある質問
	- 工数2倍になる？
		- 1999年にユタ大学の実験が行われる
			- 内容：ペアとソロで開発をさせ、それぞれで事前に用意したテストの通過率を見る
			- 結果
				- 工数1.15倍
				- テスト通過率1.15倍
					- 品質向上
				- コード行数0.85倍
					- シンプル設計
			- 結論
				- 工数自体は少し大きくなるが、品質の向上とシンプルな設計により後々の改修工数が下がるため、初期工数が少し上がる以外はメリットが大きい
	- 集中できる
		- 実際やってみると非常に集中する（らしい
			- チョコレートとか用意すべし
	- すべてペアでやる？
		- 色々意見はある
		- 著名なスクラムトレーナーのジム・コプリーンの意見では、リスクの大きい作業やクリエイティブな作業に効果が大きいらしい

### TDD（テスト駆動開発）

- テストコードと製品コードを対にして作っていく開発手法
- なぜテストが必要か？
	- アジャイルでは動くソフトウェアが重要になるので、 動くソフトウェアの担保にテストが必須
	- アジャイルでは変化への柔軟な対応が必要であり、そのために既存コードへの修正も頻発する
		- テストがない状態で既存コードを修正するとデグレが発生する危険が多い
	- テストしやすい設計＝良い設計
		- テストできないということはモジュールの分割が適切でない
			- 適切なモジュール分割＝高凝集度、低結合
- 3種のテスト
	- ユーザーテスト
		- ユーザーの言葉でシステムの動作を例示し、そのとおりに動作するかのテスト
	- 開発者テスト（ユニットテスト）
		- モジュール単位でのテスト
		- TDDでは製品コードを書く前にテストコードを定義する
			- 手順
				- 目的の製品コードに対するテストコードを先に書く
				- テストを実行して失敗させる
				- テストを通過する最もシンプルなコードを書く
				- テストを成功させる
				- リファクタリングする
				- 繰り返す
	- 品質保証テスト
		- TODO 本書で書いてなかったので概要調べとく
- よくある質問
	- 効果について
		- 2002年のノースカロライナ州立大学の実験
			- テスト駆動グループと出ないグループでプログラミングを行う
			- 事前に用意したテストの通過率の高さを測る
				- テスト駆動グループのほうが通過率が高い結果に
	- 全部やる？
		- 難しいかも
			- 特にUI周り
				- UIとロジックを分離・独立してテスト可能にするのもあり
				- UI用テストツールもある
			- 単純なgetterとかは不要かもね
			- PJ、製品による

### リファクタリング

- 外側から見た動きを変えずに内部構造を変える再設計
	- テスト駆動開発の一部
- アジャイルは必要なところから開発する関係から、ダブリなどが発生する可能性がある
	- リファクタリングをすることでシンプルな設計を維持する
		- 設計がシンプルになることで変化への対応がしやすくなる
		- ただしテストコード無しでやるのは危険なのでテストコードがある前提

### 継続的インテグレーション（CI）

- 常時結合して動作確認するテスト（？）手法
	- 結合＝別々に作られたものを一つにまとめる
- メリット
	- 仕様の思い違いや、コミュニケーションミスによる不具合がいち早く発覚する
		- リリース直前にだけインテグレーションテスト行うと、たとえ不具合が発覚しても修正するのに十分な時間が取れない

## 個人用補足(ScrumBootCampから)

### プロダクトバックログの作成

- POが管理
  - といってもPOが完璧なものを仕上げる必要はない
    - スプリント計画の他のチームメンバーとの対話で補足して行く
  - 順位は開発チームの作業順を決めるための重要な情報なのでちゃんと決める
    - 必須とか超重要とか普通とかの大分類でもOK
- 具体例
  - 蔵書管理システムバックログ
    - 必須・超重要
      - ユーザとして、蔵書管理システムのアカウントを作る機能が欲しい。その結果、蔵書管理システムを利用することができる
      - ユーザとして、蔵書の登録を行う機能が欲しい。その結果、ユーザの保持している書籍を蔵書管理システムに反映できる
      - ユーザとして、蔵書を一覧表示する機能が欲しい。その結果、今保持している蔵書を確認できる
    - 重要
      - ユーザとして、蔵書を検索する機能が欲しい。その結果、ある蔵書を保持しているかの確認ができる
      - ユーザとして、蔵書にタグをつける機能が欲しい。その結果、蔵書をカテゴリ分けすることができる
    - 普通
      - ユーザとして、hontoで購入した本を自動で蔵書に登録する機能が欲しい。その結果、蔵書を登録する手間が省ける
      - 管理者として、登録されている数が多い蔵書を表示する機能が欲しい。その結果、新しい書籍を作成する上での参考にできる

### スプリント計画

- やり方
  - 1部
    - POがプロダクトバックログの内容について説明
      - 質疑応答
        - これ足りてない
        - ここもう少し詳しく
        - etc
    - プロダクトバックログの各項目について見積もりを行う
      - 各プロダクトバックログの項目について大まかに見積もりを行う
        - 全部やってもいいが、とりあえず優先度高いものや必須のものを行う
        - 見積もりは相対見積もりで行う
          - ベース決め
            - 全員がわかるもの
          - 他はベースと比較してどれくらいかで測る
            - ベースにかかる時間がわかれば、各バックログにかかる時間がだいたいわかる
              - 時間がわかれば1スプリント内でやれるバックログも大体見当がつく
                - 1スプリントでできる作業量をベロシティという
                  - スプリント内でできる作業を考える上での基準
        - 見積もりに際して疑問があればPOに聞く
    - スプリントで実行するプロダクトバックログについて取り出す(スプリントバックログの作成)
      - 割り込みやらを考慮して1日8時間計算ではなく5,6時間で考える
      - スクラムに慣れてないうちは少なめに
      - ゴールは明確にする(完了の定義)
        - レビューでどういったデモを行えば完了とするか？
        - publicメソッドのテストコードがあるか？
        - 調査タスクは調査した内容をwikiにまとめてあるか？
        - 最新の仕様をwikiにまとめてあるか？
        - masterブランチ（もしくはデモ用ブランチ）にコードが反映されているか？
  - 2部
    - スプリントバックログの内容を詳細なタスクを洗い出す
    - タスクごとに見積もりを行う
      - 絶対時間(割り込み時間なしでの作業時間)で
      - プラニングポーカーとか使うと良い
        - 基準は4時間とかで
      - 大きすぎるタスクは分割する
        - 1タスク4時間とかが理想
    - 見積もった結果、想定より時間がかかりそうだとわかったら？
      - POと相談してスプリントバックログの内容を調整
- かかる時間
  - 1スプリント2週間だと4時間くらい