『アジャイルな見積りと計画づくり』のまとめ
今行なっているプロジェクトの期日が比較的ゆるい、ということで、〆切意識がとても薄くなってしまい、プロジェクトの終了が延び延びになってしまっている。
これは由々しき事態、ということで、見積り意識を改めるべく『アジャイルな見積と計画づくり』を読み始め。
とても良い本だったので、まとめておきます。
なぜ計画づくりに失敗するのか
- プロジェクトの3分の2近くは、コスト見積りを大幅に超過する
- プロダクトのフィーチャの64%は、めったに、あるいはまったく利用されない
- 平均的なプロジェクトは予定スケジュールの2倍以上かかる
- フィーチャではなく作業を計画している
- 顧客にとっての価値の単位はフィーチャであるので、計画づくりでは、作業ではなくフィーチャを単位にすべき
- 作業は早く終わらない
- パーキンソンの法則:「仕事の量は、完成のために与えられた時間をすべて満たすまで膨張する」
- マルチタスク化が遅れを助長する
- マルチタスク化は生産性に甚大な悪影響を与える
- クラークとウィールライトによるマルチタスク化の研究で、個人が3つ以上の作業を並行して進めると、価値を生み出す作業に使える時間が大幅に減少することがわかった
- 2つの作業を変更に進めると、片方の作業が進められなくなったときに、もう片方の作業に切り替えることができるため、効率があがる
- マルチタスク化が従来のプロジェクト計画で問題になるのは、主に2つの理由による
- 1点目は、作業を割り振るのが実際に着手するよりもずっと前であり、その時点では効果的な作業分担ができない点
- 作業をグループではなく、個人に割り当てていることも問題をさらに深刻にしている
- 2点目は、プロジェクトメンバー個々人の稼働率を高めることを重視しがちなこと
- 変化に対処するためのゆとりがほしい
- 1点目は、作業を割り振るのが実際に着手するよりもずっと前であり、その時点では効果的な作業分担ができない点
- 優先順位の順にフィーチャを開発していない
- 計画に作業を記述するときに、ユーザーや顧客にとっての価値による優先順位づけをしていない
- 開発チームに都合の良いように優先順位と作業順序を決めてしまってはだめ
- 不確実性を無視している
- 初期の要求分析において、完璧で漏れのないプロダクト仕様を策定できることを前提にしている
- ユーザーの気が変わらないと決め込んでもいる
- プロジェクトの初期段階では不確実性も最大であるから、この段階の見積りにも不確実性が反映されるべき
- そのための1つのやり方として、幅を持った期間として完了日を表現する方法がある
- プロジェクトが進行するにつれて不確実性とリスクは低減していくのだから、見積りの精度を向上させることができる
- 不確実性に対処していく最善の方法は、繰り返すこと。プロダクトがどうあるべきかという不確実性を低減させるには、短いイテレーションで作業するとよい。数週間に一度は機能するソフトウェアをユーザーに見てもらう
プロジェクトへのアジャイルなアプローチ
- プロセスやツールよりも、人と人との交流を
- 素晴らしいツールとプロセスを使っている凡庸なメンバーのチームよりも、凡庸なツールを使う素晴らしいメンバーのチームのほうが間違いなくすぐれた結果を出せるから
- アジャイルプロセスは人間一人ひとりの持つ強みと弱みを認め、それを活用する。誰でも同じようにできるようにしようとするプロセスとは対照的である
- 計画に従うよりも、変化に適応することを
- アジャイルチームにとって、計画とは未来に対する1つの見解でしかない
- 短いイテレーションで作業する
- イテレーションごとに成果をあげる
- 1回のイテレーションが終わるまでに、チームは要求を、数苦無くとも1つはコーディングしてテストをおこない、リリース可能なソフトウェアとして統合する
- 重要なのは、いつでも提供できるという点で、イテレーションごとの成果を毎回毎回、実際にユーザへ提供するチームはほとんどない
- 追加したあらゆるフィーチャは、コーディングされているのはもちろん、テストもされた状態で、リリース可能な品質に達していなければならない
- 1回のイテレーションで、ユーザーや顧客が満足できるようなひとまとまりのフィーチャを実装できることはまずないため、より大きな単位としてリリースの概念を導入する
- リリースは、関連するひとまとまりのフィーチャを完成させるだけの長さが必要なので、複数のイテレーションで構成される
- ビジネス上の優先度を優先する
- アジャイルチームは2つのやり方で、ビジネス上の優先度を大切にしながら開発を進める
- 1つ目は、プロダクトオーナーが指定した順序どおりにフィーチャを提供すること
- プロダクトオーナーはリリースに含めるフィーチャとその優先順位を決める。彼の判断によって、組織がプロジェクトへ投資して得られる利益を最適化できることが期待されている
- ビジネス上の優先度を重視する手法の2つ目は、アジャイルチームがユーザーにとって価値あるフィーチャを実装し、提供することに注力すること
- ユーザーにとって価値あるフィーチャを単位とするための最善の方法の1つが、ユーザーストーリー
- ユーザーストーリーは、システムについて、ユーザーまたは顧客の視点からフィーチャの概要を記述したもの
- 次のような形式でユーザーストーリーを考えてみると便利である
- 「<ユーザーの種類>として、<機能や性能>がほしい。それは<ビジネス価値>のためだ」
アジャイルな計画づくり
- 複数のレベルでの計画づくり:アジャイルチームは計画を3つの水平線(リリース、イテレーション、今日)という複数レベルに分けることで、レベルごとで対象にしているものに焦点を絞った計画づくりを行う
- プロジェクト
- 戦略
- リリース(チケット)
- リリースプランニングは、チームとプロダクトオーナーとが協力しながらプロダクトオーナーの満足条件を探っていくことから始まる
- リリースプランニングのゴールは、プロジェクトのスコープ、スケジュール、リソースについて回答を出すこと、これらはすべて満足条件の対象である
- 良いリリース計画とは、プロジェクトの期間を通して、イテレーションごとに更新されるもの
- 実現可能な解決策を見つけられないなら、満足条件を変える必要がある
- リリースプランニングと満足条件の探索とを何度も繰り返す理由はここにある
- イテレーション(週次)
- 今日(日次)
- スタンドアップミーティングで、作業の調整と同期化をおこなう
- この場で、計画をつくり、評価し、見直す
- 計画の焦点をタスクに絞り、どうやってタスクを完了させるかという視点から個々人の作業の調整を行う
- 繰り返し確認する
- なんとなくではなく数値化して確認する
- プロダクトへの追加機能の開発を通じて開発チームが得た知見は、次回以降の計画づくりに活かせる
- また、機能が追加された状態のプロダクトをユーザーやユーザー候補に見せれば、新たな発見が得られる可能性も
- アジャイルチームはこうした変化を計画に取り込むことでプロダクトの価値を高めていく
見積りの技法
- 見積り対象はタスクではなく、ユーザストーリー
- 見積りにおいても収益逓減の法則が働くため、労力をかけすぎないようにする
- 作業をする当人が一番正確に見積もれるが、チームで開発を行うのであればチームで見積もる
- 見積りのスケール
- 人は10倍以内のものならうまく見積もれる→見積り対象をその範囲に収める
- 見積りスケールにはフィボナッチ数列が適している
- 見積りの技法
- 専門家の意見
- 対比:相対的な大きさで見積もったほうがより正確な見積りになることも
- 三角推量(triangulation)がよさそう p.78
- 分割
- 1つのストーリーやフィーチャを、見積りしやすいように小さく分ける
- やりすぎには注意
- プランニングポーカー p.79
- アジャイルチームで一番うまくいくことがわかった
- 専門家の意見の意見、対比、分割のすべてを組み合わせ、楽しみながら迅速かつ信頼できる見積りを出せる
- プランニングポーカーのゴールは、労力ライン上の左のほうにある点に辿りつくこと
- プランニングポーカーがうまくいく理由
- 複数の専門家の見解をまとめた見積りを実現
- 活発な対話を引き出し、見積り根拠を説明することになる
最後までお読みいただきありがとうございます!
参考になれば幸いです。
CoffeeScriptの基礎まとめ その7
今回は最終回、関数についてです。
関数はJavaScriptだと少し面倒ですね。
私もJavaScriptの中で苦手なところです。
例えば、JavaScriptだとこんな感じに書きます。
var hello; hello = function(s) { if (s == null) { s = "manaka"; } return alert("hello!, " + s); }; hello("monaka");
CoffeeScriptだったらこれを次のように書けます。
hello = (s = "manaka") -> alert "hello!, #{s}" hello("monaka")
また、返り値のある関数の書き方を見てみます。
sum = (a, b) -> a + b
JavaScriptではこんな感じ。
var sum; sum = function(a, b) { return a + b; };
最後までお読みいただきありがとうございました。
CoffeeScriptの基礎まとめ その6
今回はループについて見ていきます。
まずは配列を題材にして。
for i in [0..3] alert i
JavaScriptだとこうなる。
var i, _i; for (i = _i = 0; _i <= 3; i = ++_i) { alert(i); }
次はもう少し長めのcode.
a = ["tanaka", "manaka", "monaka"] for i in a alert "hi, #{i}"
これをJavaScriptだと、長々と書くことになります。
var a, i, _i, _len; a = ["tanaka", "manaka", "monaka"]; for (_i = 0, _len = a.length; _i < _len; _i++) { i = a[_i]; alert("hi, " + i); }
indexが欲しい場合は、次のようにします。
a = ["tanaka", "manaka", "monaka"] for i, index in a alert "hi, #{index}:#{i}"
次に、連想配列の場合。
sales = "tanaka": 100 "manaka": 200 "monaka": 300 for key, value of sales alert "#{key}: "{value}"
これをJavaScriptで書くとなると、次のようになります。
var a, i, _i, _len; a = ["tanaka", "manaka", "monaka"]; for (_i = 0, _len = a.length; _i < _len; _i++) { i = a[_i]; alert("hi, " + i); }
CoffeeScriptの基礎まとめ その5
存在チェックの演算子を見ていきます。
?で書くところはRubyに似ている気がします。
alert "ok" if name?
JavaScriptで書くとこうなります。けっこう長くなりますね。
if (typeof name !== "undefined" && name !== null) { alert("ok"); }
CoffeeScriptの基礎まとめ その4
今回は条件分岐と比較演算子について見ていきます。
まず、条件分岐の書き方を簡単に見てみます。
signal = "red" if signal == "red" alert "stop!" else if signal == "green" alert "go!" else alert "caution!"
次に比較演算子を簡単に紹介します。
- is : ===
- isn't : !==
- not : !
- and : &&
- or : ||
CoffeeScriptでは、比較演算子をまとめて、以下のように書くことも可能です。
x = 20 if 10 < x < 30 alert "true!"
これをJavaScriptで書こうとすると、少し面倒なことになります。
var x; x = 20; if ((10 < x && x < 30)) { alert("true!"); }
if文に関しては、Rubyのように後置で用いることも可能です。
x = 20 alert "true!" if 10 < x < 30
最後に、switch文を使った条件分岐についてです。
JavaScriptと異なって、break文が必要ありません。
signal = "red" switch signal when "red" then alert "stop!" when "green" alert "go!" else alert "caution"
これをJavaScriptで書くと、以下のようになります。
var signal; signal = "red"; switch (signal) { case "red": alert("stop!"); break; case "green": alert("go!"); break; default: alert("caution"); }
CoffeeScriptの基礎まとめ その3
今回は、配列と連想配列を扱います。
CoffeeScriptだと、配列や連想配列もすっきり書けます。
全体的にRubyっぽい書き方が採用されている気がします。
CoffeeScriptでは以下の様な書き方ができます。
a0 = [1, 2, 3, 4] a1 = [ 1, 5, 8 2, 3, 4 ] a2 = {"sato": 100, "sasaki": 200} a3 = "sato": 100 "sasaki": 200 a3 = "sato": "sales": 250 "cost": 80 "sasaki": "sales": 250 "cost": 40 a4 = [1...5]
一方、これらをJavaScriptで書きなおすと下のようになります。
var a0; a0 = [1, 2, 3, 4]; /////////// var a1; a1 = [1, 5, 8, 2, 3, 4]; /////////// var a2; a2 = { "sato": 100, "sasaki": 200 }; /////////// var a3; a3 = { "sato": { "sales": 250, "cost": 80 }, "sasaki": { "sales": 250, "cost": 40 } }; /////////// var a4; a4 = [1, 2, 3, 4];