####「アジャイルソフトウェア開発の奥義」から学んだことを書き殴る。
全29章からなる分厚い本です。
この記事は「アジャイルソフトウェア開発の奥義」から学んだことを忘れないために要点を整理する目的で書いています。
この本はアジャイル開発、オブジェクト指向、デザインパターンの概要から実践例の紹介まで取り扱っています。
すべてを完全に理解してから整理しようとすると大変時間がかかるのでアジャイル開発に焦点を絞って書いています。
####感想から
この本をざっくり読んだけでもはっきり感じた所感、それは私がこれまで携わってきたプロジェクトで行われているアジャイル開発はアジャイル風開発であってアジャイル開発ではなかったと。
顧客と開発者の関係が適切でないため計画フェーズではストーリーサイズの最適化、ストーリーポイントの見直し、速度計算の見直しがなくシャトルランを続けることになり計画フェーズでの狂いは実装フェーズでは残業の常態化、中途半端なテストファースト、中途半端なリファクタリングという悪影響をもたらしていると感じました。
####1-1 アジャイルプラクティス
概要 |
---|
プロジェクト成功の法則 1). 会話 > プロセスやツール 2). ソフトウェア > 包括的なドキュメント 3). 顧客との協調 > 契約交渉 4). 仕様変更 > 計画 |
アジャイル開発の目的 |
---|
プロジェクトのプロセスが雪だるま式に肥大化してしまう悪循環を断ち切る。 アジャイル開発の法則は業務の関心ごと(顧客の要求を満たすこと)に集中するためのテクニック。 |
#####原則
- 最優先事項は顧客を満足させること
- 要求変更を歓迎し、顧客の市場での優位性を確保する
- 実働可能なソフトウェアの納品を頻繁(数週間程度)に行う
- 顧客と開発者はプロジェクト全般を通して日々働く
- やる気のある開発者をプロジェクトの中心に置き、サポートし信頼しプロジェクトを完遂させる
- チームでの情報伝達の最善な方法は直接話し合うことである
- 実働するソフトウェアが進捗状況の尺度
- 持続できるペースで開発する(シャトルランではなくマラソン)
- 高度な技術と優れた設計がアジャイル性を高める
- やらなくていいことはしない(You ain't gonna need it.)
- 最高のアーキテクチャ、仕様要求、設計は自己管理能力のあるチームから生まれる(他人任せはダメ!)
- 定期的にプロジェクトの見直し調整を行う
1. 最優先事項は顧客を満足させること
顧客を満足させるために下記のことがわかっている。
最初に納品される機能が少なくて乏しいほど最終的な納品物の品質は高くなる傾向がある。
また、頻繁に納品すればするほど最終的な納品物の品質は高くなる傾向がある。
このことからアジャイル開発ではプロジェクト初期の段階から数週間のスパンで機能を実装し納品することを繰り返していくことを目指す。
2. 要求変更を歓迎し、顧客の市場での優位性を確保する
顧客を満足させるための仕様変更、仕様追加は歓迎ということ。
開発者と顧客が一つのチームとなって市場で優位性を確保できる納品物の製作に取り組むべし!
3. 実働可能なソフトウェアの納品を頻繁(数週間程度)に行う
仕様書やプロジェクト計画書だけでは机上の空論でしかない。
プロジェクトの目標はあくまで顧客を満足させるソフトウェアの納品であるということ!
早い段階から動くソフトウェアを納品し続けることで、作成物が顧客の要求を満たしているモノか確認作業が可能になる。
4. 顧客と開発者はプロジェクト全般を通して日々働く
顧客と開発者は信頼し合いコミュニケーションを頻繁に行なう必要がある。
5. やる気のある開発者をプロジェクトの中心に置き、サポートし信頼しプロジェクトを完遂させる
アジャイル開発において成否のカギを握る要素は「人」である。
開発者が開発環境やプロセスなどに煩わせることなく、業務の関心ごとに集中できるような環境を作る必要がある。
6. チームでの情報伝達の最善な方法は直接話し合うことである
アジャイル開発では会話こそがコミュニケーションのメインツールになる。
プロジェクトの子細をドキュメントに記すことはない。
ドキュメントは基本的には作成しない。
新しく迎え入れたチームメンバーにとって**ドキュメントは「コード」と「チーム」**である。
7. 実働するソフトウェアが進捗状況の尺度
プロジェクトの進捗度は納品した機能数である。
8. 持続できるペースで開発する
アジャイル開発では納品した実績をもとに戦略的にリリースプランニングを練り込んでいく。
持続可能なペースで走りださなければ途中で失速し戦略に破綻が生じてしまう。
9. 高度な技術と優れた設計がアジャイル性を高める
持続可能なペースで走り続けるコツは「品質」である。
無駄に複雑なコードや乱れたコードは後で直そうとせず今すぐ直すこと。
10. やらなくていいことはしない(You ain't gonna need it.)
アジャイル開発ではいきなりシステム全体を作り上げようとはしない。
目的に叶うものを最もシンプルな方法で段階的に実装していく。
明日発生するかもしれない問題を予測したり、前もって処理しようと時間を割くことにあまり意味はない。
できるたけシンプルに高い質で。
11. 最高のアーキテクチャ、仕様要求、設計は自己管理能力のあるチームから生まれる(他人任せはダメ!)
アジャイル開発では自己管理能力があるチームである必要がある。
要求される「責務」はチーム全体に伝えられ、チームとして「責務」を果たす最善策を探求する。
チームはプロジェクトの全ての局面で行動を共にする。
個人がチーム全体に対して意見することが許される。
「アーキテクチャ」「仕様」「要求」などの責任はチーム全体が(つまり誰か1人ではなくチームの1人1人が)責任を持っている。
12. 定期的にプロジェクトの見直し調整を行う
組織や規則、慣例などは漸進的に見直す。
状況は刻一刻と変化している。
####1-2 エクストリームプログラミングの概要
概要 |
---|
エクストリームプログラミング(XP)は有名なアジャイルメソッドの1つ。 顧客をチームに迎え入れ、短期納品可能なユーザーストーリーを短いリリースサイクルで納品していく。ストーリーは相対的な時間で管理されるので進捗の精度も上がる。 |
目的 |
---|
XPはアジャイル開発の手法をまとめたものである。 これらの手法(いくつかを加えたり変更したりしたもの)をプロジェクトに取り入れ開発を行っていくスタイル。 |
#####手法
- チームメンバーとしての顧客
- ユーザーストーリー
- リリースサイクル
- 受入テスト
- ペアプログラミング
- テストファースト(TDD)
- 継続的なインテグレーション
- 持続可能なペース
- オープンワークスペース
- 計画ゲーム
- シンプルな設計
- リファクタリング
- メタファー
1. チームメンバーとしての顧客
顧客と開発者は親密に仕事をすることが望ましい。
開発は顧客の満足度を高めることに関心があるし、顧客が抱える問題を解決するためには開発者に理解してもらわなければならない。
2. ユーザーストーリー
- 仕様概略
計画を立てる段階では実装するための作業量を見積もれる程度の情報があればよい。
この段階では子細まで落とし込まず、お互いが同意した内容をインデックスカードに簡単に書き留める。 - 見積り時間
開発者はインデックスカードに大体の時間を記入する。 - ユーザーストーリー
インデックスカードに記載されたユーザーストーリーは仕様要求の覚書であると同時にプランニングツールとなる。
顧客はユーザーストーリーのプライオリティ(優先順位)とコスト(見積り時間)を考慮しながらどの機能を実装するかスケジュールを立てる。
3. リリースサイクル
XPプロジェクトでは2週間間隔でリリースする。
2週間のイテレーションでリリースされる機能はいづれかのユーザーストーリーである。
イテレーションの終わりに要求レビューとしてデモを行う。
-
イテレーションプラン
大抵2週間程度のイテレーションごとに小さな機能(ユーザーストーリー)を実装し納品する。
開発者は前回のイテレーションでこなした仕事量を参考にして次のイテレーションでの仕事量を見積もる。
顧客は見積りを超えない範囲内で好きなユーザーストーリーを好きな数だけ選択できる。
顧客はイテレーションがスタートしたらイテレーションでのストーリーや作業の優先順位を変えてはいけないことに同意する。
開発ははストーリーをタスクレベルへ分割することは自由。 -
リリースプラン
通常は3か月ごとに1回のリリースプランを作成する。
これはいくつかのイテレーション(大抵6回程度)を1つにまとめたプランのことで製品に組み込めるような本格的なソフトウェアのリリースになる。
開発者は前回のリリースでこなした仕事量を参考に次のリリースでの仕事量を見積もる。
顧客は見積りを超えない範囲内でリリースしたいストーリーを好きな数だけ選択できる。
顧客が選択したユーザーストーリーはいつでも変更可能で追加したり、キャンセルしたり優先順位を変えることができる。
4. 受入テスト
受入テストはユースケースとして記述され自動で実行できるように実装する。
受入テストもまたイテレーションが繰り返されるたびに漸進的に進化する。
5. ペアプログラミング
納品するコードはすべてペアプログラムで生み出される。
2人で詳細設計を行い1人がコーディング、1人がレビューを行う。
2人の役割は何度も入れ替わり、ペアそのものも1日1回は組み替える。
こうした過程を経てチーム全体に知識が浸透する。
ペアプログラミングは作業効率が落ちることなく欠損率が減少する手法である。
6. テストファースト(TDD)
コードはすべて失敗するユニットテストをパスさせる目的で書く。
まず、機能が実装されていない失敗するユニットテストを書く。
次にそのテストをパスさせるためのコードを書く。
テストケース(ユニットテスト)を作ってからテストをパスさせるコードを書く。
数分程度で実装できる小さなテストケースの作成と実装を繰り返していきながら機能を実装していく。
7. 継続的なインテグレーション
実装中の機能は切りのよいタイミングで(1日に何度も)システムにチェックインしながら作業を進めていく。
8. 持続可能なペース
持続可能なペースで走りださなければ途中で失速し戦略に破綻が生じてしまう。
XPでは残業は許されない。
但し、リリース最終週の時点でゴールが見えていて全力で走れば辿りつけると判断したら全力で走ってもよい。
9. オープンワークスペース
ストーリーやタスクボード、UMLなどが張り出してあり(目の付く場所にある)、メンバーがオープンな環境で作業をする。
メンバー同士がいつでもコミュニケーションが可能な環境では作業効率が大幅にあがる。
10. 計画ゲーム
顧客はストーリー(各機能)のビジネス的な重要度(プライオリティ)を決定する。
開発者はストーリー(各機能)の作業時間(コスト)を計算する。
開発者が見積りを提示し、顧客はリリースサイクルでの実装してほしいストーリーを選択する。
シンプルな設計
出来る限りシンプルで表現性に富んだ設計になるように心がける。
やらなくていいことはしない(You ain't gonna need it.)
最初からインフラを考慮しないし、DBも選択せず、考えうる限り最もシンプルな方法かつ正常に動作することに注力する。
- 動くだけの最もシンプルなものだけを設計する
現行のストーリーの一群を処理できる方法のうち可能な限りシンプルな方法を選択する。
ファイルシステムで実装できるならDBを持ち出すまでもない。
ストーリーが実装可能な手段のうち実質的に最もシンプルだと考えられるソリューションを選択する。 - あとで必要になんてならない
いずれ必要になることはわかっていても、いつ何をどれだけ必要になるのかまでは現時点ではわからないし考えても意味がない。
必要になった時にサポートできるように準備しておくことのほうが大切である。
ただし、今のうちに用意したほうが経費が節約になり、顧客の満足度が高くなることが明らかな場合は検討する必要がある。 - 同じことは2度としない(Don't Repeat Yourself)
コードの重複は避けろ。
コードの重複を発見したら基本クラスや関数を作成して重複を取り除く。
酷使しているけど微妙に違うアルゴリズムは関数に書き換えるかTemplate Method Patternを使う。
助長性を避ける最善の法は抽象化。
12. リファクタリング
リファクタリングの概念。
機能を追加しバグをつぶしていくうちにコードは煩雑になりやがて手が付けられなくなる。
コードに手を加えたら必ずユニットテストを実行し何も壊れてないことを確認する。
13. メタファー(全体像、大局観)
エンジニアは目に見えることに囚われがちだし、プロダクトに関するすべての事をロジカルに捉えようとすることに執心してしまう。
時にメタファーが最も重要な意味を持つことがある。
以下は将棋の羽生善治先生のインタビュー記事より抜粋したものです。
「ロジックの組み立て方が前よりも優れてくると、曖昧なところでの判断が鈍くなる。」
「ミスをしたくないとか、完璧でありたいと思うこともあるんですけど、ちょっと遊びや揺らぎの部分があるほうが、より自分なりに納得できることが経験則として分かっているので。全部ロジックで完結して仕上がっているものは、意外と完成度が高くないんじゃないかなと思っています。説明できることはマニュアル化できるので、それ以外のところに個性やオリジナリティーが潜んでいるんじゃないかなと。」
羽生先生のコメントはメタファーの重要性を示している一例だと感じたため引用させて頂きました。
####1-3 プランニング
概要 |
---|
プロジェクトの最初期、顧客と開発者は重要なユーザーストーリー(≒ユースケース)の洗い出しを行う。 出来るだけヌケ漏れがないように努めるが完璧に出し切ることは困難(ほぼ無理)である。 次に開発者はユーザーストーリーの見積もりを相対時間で算出する。 顧客は優先度と開発コスト(時間)からユーザーストーリー実装の順番を決める。 |
- ユーザーストーリーの洗い出し、見積り、スパイク・分割・速度
- リリースプランニング
- イテレーションプランニング
- タスクプランニング・進捗確認ミーティング(中間ミーティング)
- 進捗確認ミーティング(中間ミーティング)
- イテレーション
1. ユーザーストーリーの洗い出し、見積り、スパイク・分割・速度
- ユーザーストーリーの洗い出し
プロジェクトの最初の段階で顧客と開発者は重要なユーザーストーリーを可能な限り洗い出す。
ただし、すべてのストーリーを出し切る必要はない。
ストーリーは後で追加することも可能であり、開発者は歓迎する。 - コストの見積もり
開発者はストーリーを実現するために必要な時間を見積もる。
この段階での見積もりは大雑把なものでよい。
時間はストーリー実装の相対時間を表すポイント数で算出する。 - 分割
長すぎるストーリーは小さく見積りがちだし、小さすぎるストーリーは大きく見積もがちになる。
「実践ユースケース駆動開発ガイド」では主語、述語、目的語でシンプルにユースケースを記述することを推奨している。 - 速度
相対的な見積りからは絶対的な時間は割り出せない。
ストーリーの最適なサイズを知るには相対的なストーリーポイントの絶対値を知る必要がある。
ストーリーポイントの絶対値を速度と呼ぶ。
速度の精度が上がるほどストーリーの最適なサイズが正確に知ることが出来るし、リリースプランで提示するストーリーの見積もりの精度も向上する。 - スパイク
最初にストーリーのプロトタイプを作成することで速度をつかむとっかかりができる。
この作業をスパイクと呼ぶ。
2. リリースプランニング
リリースプランニングではリリース期間のサイズを定める。
通常リリース期間は2~4か月程度。
次にリリース期間中にどのストーリーを実装したいか選択する。
この時、ストーリーポイントの合計がリリース期間を超えるサイズにしてはならない。
イテレーション前であれば選択したストーリーを変更することができるが、イテレーション期間のものは変更できない。
ストーリーを選択する指標はストーリーのプライオリティとコストである。
プライオリティとコストがわかればコストパフォーマンスを知ることができる。
リリース期間を経るにつれ速度計算の精度は高くなっていく。
イテレーションプランニング
リリース期間が決まったら、イテレーションサイズを定める。
イテレーション期間で実装したいストーリーは顧客が選択することができる。
この時、ストーリーポイントの合計がイテレーションサイズを超えてはならない。
たとえストーリーがすべて実装できなくても定められた日にイテレーションを終了しなければならない。
開発者は速度を計算する。
- イテレーション速度計算
速度(絶対時間) = 総作業時間 / 完了したストーリーの総ポイント
4. タスクプランニング・進捗確認ミーティング(中間ミーティング)
イテレーションごとに開発者にはタスクポイントを割り振る。
イテレーション開始時に開発者はストーリーをタスクレベルに分割しタスクポイントを設定する。
分割したタスクは顧客に提示する。
抽出したタスクはチームメンバーが目に見えるところに表示されメンバーは自由にタスクを選択しサインアップしていく。
タスクが終了すると開発者に割り振られたタスクポイントは消費されていく。
タスクポイントを消費しきった開発者は次のイテレーションまで次のタスクを行ってはならない。
すべての開発者がタスクポイントを消費しきった段階で残タスクがあった場合はチーム内で調整し残タスクにとりかかる。
逆にタスクをすべて終了した段階でタスクポイントに余裕がある場合はストーリーの追加を検討する。
5. 進捗確認ミーティング(中間ミーティング)
イテレーションの中間地点で開発チームはミーティングを開き、進捗確認を行う。
この時点でストーリーの半分が実装されていなければならない。
ストーリーが8個、タスクが40個だった場合、ストーリーが4つ実装されているということである。
タスクが20個消化されているという意味ではないことに注意。
6. イテレーション
イテレーションの最後に実装した機能のデモを行う。
顧客は機能の評価をし、必要であれば新しいユーザーストーリーとして開発者にフィードバックをする。