PMの面接で聞かれた「アジャイルを採用すべき場面は？」から改めて学ぶアジャイル開発

以前、とあるコンサルティングファームに関連するAIスタートアップでPMとして面接を受けていた時に以下のような質問を受けたことがあります。

*アジャイル開発とは何か説明してもらえますか？それはどのような時に採用すべき手法ですか？*

アジャイル開発については、知っているだけではなく対外的に説明できることも同等に重要です。
というのも、この習慣を導入したり改善する際にはどうしてもエンジニア以外の関係者へその意義を説得する必要があるからです。先の質問は、PMとしてクライアントに説明できるか試されたものでした。

改めて、アジャイル開発についてまとめてみました。

# アジャイル開発とは

プログラミング開発フローの大きなカテゴリーの１種です。
個別の開発フローには、スクラムと呼ばれる手法のようなものがあります。
アジャイル以外のフローには、ウォーターフォール型開発と呼ばれるものが存在します。

####どう言う時にアジャイル開発を行うか

* スピード重視
* 変化への対応
* 生産性

これらを重視する時にはアジャイル開発が向いているとされます。
「そうでないものなんてあるのか？」という質問があるかもしれませんが、
例えば、オリンピックのチケット抽選サイトや鉄道の信号システムなど、ユーザビリティがそこまで大事ではないものや正確性が大事なシステムなどはウォーターフォール型の開発でも良いでしょう。

####アジャイル開発を実践する企業例

* Facebook （自然に出来上がっている）
* Google（自然に出来上がっている）
* Salesforce

## アジャイル開発の種類
* スクラムが代表的で、６７％がスクラムを採用
* KANBAN
* XP

## アジャイル開発を支えるもの
* アナログと対話
* クラウド化
* IDE
* オブジェクト指向

![kaleidico-26MJGnCM0Wc-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507240/e123bcf7-4aa1-e738-f2b4-aa64691708dd.jpeg)


## 従来手法（ウォーターフォール型開発）の何が問題なのか
* 創造性を奪う：良いアイデアは実際の製品を見た時によく出てきたり、最後の最後に出てきたりするが、WF型の開発だと、製品が出来上がるのはプロジェクトの本当に最後だし、その時点での変更は開発コストが最も高い
* 文書でのコミュニケーションに限界がある：人→文書→人のコミュニケーションは間に
* 製品はどんなに良くても「最初のアイデア」以上にならない

---

# スクラムとは
* 1990年代はじめに作られた
* 薄いマネジメントの手法で、チーム全体が強調するためのコミュニケーションのルールを定義する
* 役割・成果物・イベントの切り口でルールが存在
* コマンド・コントロールではなくリーダーシップ・コラボレーション
* スクラムは枠組みであり、中身はアイデアで工夫をする（そのためにレトロスペクティブがある）
* その他、アジャイルの様々なプラクティスを取り入れることが必要

## ６つの特徴
1. 不安定な状態を保つ
2. プロジェクトチームは自ら組織化する
3. 開発フェーズを重複させる
4. 「マルチ学習」（個人・チーム・組織として）
5. 柔らかなマネジメント
6. 学びを組織で共有する

####チーム選定のポイント
1. 正しいメンバーを選ぶ。そして、プロジェクト途中でもグループダイナミクスを観察し、必要であればメンバーを入れ替える
2. 専門を超えて対話が起こるような、オープンな仕事環境を作る
3. 顧客やディーラーがどんな意見を持っているか、エンジニア自身がフィールドに出ていって聞くように仕向ける
4. 人事評価、報酬制度を、個人ではなくグループ評価を基本とする
5. 開発が進行していく中で、リズムの違いをマネジメントする
6. 失敗を自然なこととして受け入れる。ブラザーの例では「失敗は当たり前。鍵は、早期に間違いを見つけ、すぐに修正すること」、３Mの例では「成功よりも失敗からの方が学べることが多い。ただし失敗するときには創造的に失敗すること」
7. サプライヤーに対しても、自己組織化を促す。設計の早いタイミングから参加してもらうのが良い。サプライヤーに細かな作業を指示してはいけない。課題を提示してどのように解決するのかは任せる


## 役割
####プロダクトオーナー
* ROIの最大化が命題
* プロダクトに必要な機能の定義
* 1人の人間が担当し、会議体にしてはならない**[責任]**
* プロダクトバックログへの追加・削除・順位づけ
* 開発チームに機能を説明して理解してもらう
* プロダクトのビジョンを示す


#### 開発者
* ビジネスアナリスト、エンジニア、テスター、アーキテクト、デザイナーなどの明示的な区分けはない
* 強みを持ち寄るが、その垣根を超えて貢献しあう**[責任]**
* バックログに入っている項目を完了状態にし、製品の価値を高めていくこと
* 開発のやり方に関する決定を行う



#### スクラムマスター
* チーム全体が自律的に行動できるような場作りを行う
* ファシリテーターに近く、マネジメントを行うもののコントロール型ではなく支援型である
* サーバントリーダーシップが求められる
* メンバーの活動の障害を取り除く、時に相談やサポートを行う**[責任]**
* スクラムをうまく回すこと

## ３つの成果物
####インクリメント
* 都度のスプリントの成果物とこれまでに完成した機能の全体
* これをレビューしてオーナーが実際に製品をリリースするか決定する（出荷判断可能ソフトウェア）

####プロダクトバックログ
* 製品へ追加する機能（要求）のリスト
* ユーザーのわかる言葉で書かれている必要がある
* プロダクトオーナーが管理する
* 「高・中・低」といった優先度カテゴリをつけるのではなく、順位づけされて並べることが重要
* 製品の開発が続く間変化し続ける（それで良い）

####スプリントバックログ
* そのスプリントで実装される機能のリスト
* プロダクトオーナーの決めた順位とdeveloperの出した見積もりを勘案してスプリント計画時に決定される

## ５つのイベント
####スプリント
* 1-4wの時間枠
* 延長されることはない(重要)
* スプリントバックログの開発に集中し、インクリメントを作成する

####スプリント計画
* プロダクトバックログから今回のスプリントで開発する内容をスプリントバックログとして決定する
* その後、開発者が詳細なタスクに分割し、「スプリント内で完成できる」という自信を持てる状態にする

####デイリースクラム
* 「昨日やったこと」「今日やること」「障害となっていること」の３つを朝に共有する
* ダラダラやらない。スタンドアップでやると良い

####スプリントレビュー
* スプリントで完成したものを関係者を集めて披露する

####レトロスペクティブ
* スプリントレビューの後に行われる、ふりかえり
* 今回のスプリントでうまくいったこと、うまくいかなかったこと、どうすれば次のスプリントでよりうまくできるかを話し合う
* チーム学習・チーム改善の機会

---

# アジャイル開発のプラクティス

![you-x-ventures-Oalh2MojUuk-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507240/8f3ae1d3-4ba5-c001-bcf7-67c5f353d166.jpeg)
Photo by You X Ventures on Unsplash

#### ユーザーストーリー
* XPで提唱された
* ユーザーの言葉で書かれた機能の説明
* 従来のWF開発での仕様書に対するアンチテーゼ（従来の問題は、完璧な仕様書を作るために作り終わる頃に要求が変化しているという点である）
* 紙に書いて会話で伝えることが推奨されている、細かい点は会話で埋める（アジャイルでは対話を重視している）
* 各プロダクトバックログごとに存在する

テンプレート
> As a  /User role/
> I want /describe the feature/
> Because /the value of the feature, purpose/

#### プランニングポーカー
* 開発期間を見積もるための手法
* 比較対象となる、ある程度自明なタスクの開発期間を２と定める
* プロダクトバックログごとの工数を見積もる
* 全員のカードの中で最大と最小値を出した人は意見を述べる（短時間で）
* 意見を聞いた上で、再びカードをだす。最大で3回繰り返す
* 途中で全員のカードが一致した場合は終了、そうでない場合は平均や最大を採用する

#### タイムボックス
* 1週間を１つの箱のように捉え、タスクをその箱に詰めるボールとして可視化するもの
* タイムボックスはあふれるものであるという前提のもと、新たなタスクがボックスから溢れそうならビジネス側にもそれを理解してもらいやすくできる

#### デイリースクラム
* 進捗をバーンダウンチャートで壁に書き出す
* 定位置・定時刻・短時間で行うこと
* 「今日は早帰り」といった報告もここで行う
* 問題の議論が長引きそうな時は切り上げて二次会で話し合う（当事者だけ）
* 外部の人が参加する時は事前に参加目的をチームメンバーに共有するほか、発言は最初か最後だけに絞るなど、余計なインターセプションを入れさせないように工夫する（プロジェクト内の人はブタ、外部の人はニワトリ）

#### レトロスペクティブ
* スプリントの最後に実施する「気づきの共有」と「今後への活かし方」の議論
* 責任追及の場や課題解決リストを作ることではないので、本気で話し合える雰囲気作りと司会の進行が特に重要
* トピックはプロダクトに限らない。プロセス（開発の仕方）のことや顧客との関係、日々のコミュニケーションのことなど多岐に渡るべき
* 「部屋の空気が悪い」とかもあってOK
* Keep Problem Try

#### タスクかんばん
* 現在チームが取り組んでいるタスクを壁に張り出す
* スプリント計画時にタスクを全て書き出して付箋で貼っておく
* 毎朝、各人がタスクにサインアップする（アサインされるのではなく、自分で取りに行く）
* フェーズは様々、Todo, Doing, Done, UIdesign, Test, Documentationなど分かれていてもいい
* タスクの粒度は、大きすぎないように気をつけること。大きすぎるタスクは、「毎日動かないカード」を生んでしまう。著者の経験では2−3時間のタスク粒度に抑えることを推奨している

#### バーンダウンチャート
* タスクがあと何時間で終わるかを可視化、エクセルで実施せずアナログ手段を用いる
* 理想線を描き、その後毎日の所感を書いていく
* 「何％終了したか」ではなく、そのタスクについてあと何時間ぶんの作業があるのかを述べる（透明性の確保）

#### ペアプログラミング
* パソコン１台で2名でプログラミングを行う
* 15分交代程度で実施する
* 次のような項目はミスを起こしやすい
	* 変数の名前
	* アルゴリズム
	* DBテーブル設計
* パイロット、刑事事件捜査、スキューバダイビングなどリスクの高い仕事はペアで行われる
* リアルタイムのコードレビューや知識の共有になる
* 全ての開発をペアで行った方が良いかには意見が分かれているよう。リスクの高い部分にはペアで実施することが望ましいといっている

#### テスト駆動開発・リファクタリング
* Red, Green, Refactoringの順をたどる開発手法
* 全ての開発をTDDでできるかは意見が分かれるし、特にUIの部分に関してはテストが難しいことが多い。だからと言って諦めるというわけではなく、機能をパーツとして分離する努力を行うことが望ましい
* リファクタリングは、外部から見た動きを変えずに内部設計を変えること
* TDDと両輪で成り立つものであり、テストがあるからこそ安心してリファクタリングできる
* 最初から壮大な将来を見据えてコードを書くことがアジャイルでは推奨されないBUDF（Big Design Upfront）

#### Continuous Integration
* 従前の開発手法で存在した「統合」作業を自動化するもの
* 「統合テスト」が不要になる
* 具体的に自動化するのは例として以下：
	* プログラムのコンパイル
	* 自動テスト
	* アーカイブ化
	* ソースコードへのタグ付け
	* ステージング環境へのデプロイ
	* 受入テスト
	* 関連部署へのメール送付


# アジャイル開発経験談

![IMG_3663 (1).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507240/2781cdb5-ec92-b5e8-dfe2-8603b30bd5b4.jpeg)
(スクラムでプロダクト開発した仲間との様子)


実際の現場での課題やポイントとともに、この辺りはまた別途書いていきたいと思います。