見積もり、どうすればうまくいくか(思考垂れ流し)
「エンジニアのための見積もり実践入門」という本を読んで、見積もりに対する考察をつれづれなるままにかく。
見積もりは苦手。この機能どれくらいでできる?と言われてパッと答えられる自信はない。
見積もりが苦手な理由として一番大きいのは、自身の経験値が少ないから。
要求された機能を作ったことがないため、どれくらいの工数がかかるのか皆目検討もつかない。
本を読んだところよくアドバイスとしてあがっていたのは、機能をタスクまで分解してそれぞれのタスクに、
- 最初どれくらいの時間がかかりそうか見積もる(リード見積もり)
- タスクが完了したらどれくらい時間がかかったのか振り返る
と、自身の機能実装の経験と時間感が積み上がっていくと書かれています。
これも結局経験つんで見積もり制度あげろというのと一緒かなと思います。
他にもアドバイスがあった。
要求された機能をつくったことがない、もしくは、このライブラリがつかえるだろうという想定(もしかしたら使えないかもしれない)がある場合は、調査フェーズを設けること。
調査フェーズにより、サンプルを作ることで見積もりができるようになる。これは経験値の先取りできな感じ?
調査フェーズにどれほどの時間がとれるのか、調査フェーズの時間内で調査がおわるのかという部分も考えたいところ。
- 実装したい機能が一般的にどのように設計されるのかをしる
- 実装したい機能が自身の利用しているフレームワークで設計できるのかしる
- 実装したい機能のサンプルコードを手に入れる
- サンプルに使われているライブラリ群が自身の環境でも使えるのかどうか
- 一番よいのは、実装したい機能を調査フェーズだがちょっと作ってみて、行けるかどうか確かめる。
書いてておもったのは一番大事なのは、どこが未知なのかをしることかもしれない。
実装
設計がわからない
設計がわかるが、自身の利用しているフレームワークなどで実現できるかわからない
ライブラリどれを選べばいいかわからない(自分のユースケースを満たすのか、自分の環境でも使えるのか、既存のライブラリとの相性は悪くないのか)
そもそもライブラリがあるかわからない
組織
機能実装をする人がどれだけ時間をとれるかわからない
機能実装する人が
例えば reactで初めてtypescriptとreduxを導入してみるとき、
typescriptがわからない
reduxがわからない
の他に
typescriptでreduxをどう実装するかがわからない
というふうに組み合わせのわからないが出てくる
見積もりにおける、未知のものを見積もるときの未知のものの大きさを推測する
がばがばだし、仮定が多すぎるけど、計算式立ててみる。
未知なものは単純にそれぞれ重みが違う。例えばjsのアロー関数がわからないとreduxがわからないは重さが違いそうな気がする。
アロー関数わからない__重み1
reduxわからない__重み5
typescriptわからない__重み5
の3つがあった場合、単純な重さ合計11が予測できる。
nこの未知なものとそれぞれの重みをwで表して
未知重み単純合計 = w_1 + w_2 + ... + w_n
未知なもの同士の組み合わせがわからない場合もある。例えばtypescriptでreduxを実装する方法がわからないなど。とりあえず2つずつの組み合わせに限定して考えると未知数nこに対して、その組み合わせは nC2になる。
5つ未知なもの、それぞれ2つの組み合わせは 5C2 = 10 通り。
nこの未知なもの、それぞれ2つの組み合わせは nC2 = n*(n-1)/2 通り
未知の組み合わせ = n*(n-1) / 2
ではtypescriptでreduxがわからないは、どれくらい重たいのだろうか。ぶっちゃけ予測がつかないが、単純に重さの掛け算をしてみると25になる。他の組み合わせも合わせると
- typescriptでreduxがわからない 5 * 5 = 25
- typescriptでアロー関数がわからない 5 * 1 = 5
- reduxでアロー関数がわからない 5 * 1 = 5
合計 25 + 5 + 5 = 35
上記の数字はちょっと大きすぎる気がする。typescriptでreduxがわからないは少なくとも掛け算ではない気がする。足し算の中央値で考えてみる。
- typescriptでreduxがわからない (5 + 5) / 2 = 5
- typescriptでアロー関数がわからない (5 + 1) / 2 = 3
- reduxでアロー関数がわからない (5 + 1) / 2 = 3
合計 5 + 3 + 3 = 11
なんとなく実感通りかも?
ということで、nこの未知の組み合わせによる重みは
組み合わせによる重み = (w_1 + w_2) / 2 + (w_2 + w_3) / 2 + (w_1 + w_3) /2 + ...
= (w_1 + w_2 + w_2 + w_3 + w_1 + w_3 + ... ) / 2
= ( (n-1)*w_1 + (n-1)w_2 + (n-1)w_3 + ... ) / 2
= (n-1)(w_1 + w_2 + w_3 + .... w_n)/ 2
= (n-1)(未知の重みの単純合計)/2
未知度 = 未知の重み単純合計 + 未知の組み合わせによる重み
= (未知の重みの単純合計) + (未知の数 - 1)*(未知の重みの単純合計) / 2
= (未知の重みの単純合計)(1 + (未知の数 - 1)/ 2)
= (未知の重みの単純合計)(2 + 未知の数 - 1)/2
= (未知の重みの単純合計)(未知の数 + 1)/2
これだけ見ると、未知の大きさは、各未知の重み合計に未知数の半分程度をかけたもの
になりそうです。
ということで
- アロー関数わからない__重み1
- reduxわからない__重み5
- typescriptわからない__重み5
は、
未知度 = (1 + 5 + 5)(3 + 1)/2
= 11*4/2
= 22
となり、単純合計の2倍ていど大変であることがわかりました。
本で読んだ見積もりしにくくする要因
- 未知なもの
- あいまいな要件
- コミュニケーションコスト
人間は絶対的見積もりより相対的見積もりのほうが得意。
また一年後の予測よりも、10秒後の予測のほうが得意。
そこで、
絶対的見積もりはせず、この機能はこの機能より難しそうだねとった相対で考えていく(ストーリーポイント)
また、その際に複数にでストーリーポイントをきめていくと集合知を活かせる。
短く期間を区切って見積もりと実装のサイクルを回す。
クリティカルパスという考えもある。