初めての見積もり

はじめに
---
ソフトウェア開発を続けて何年か経つと、見積もり作業を依頼されることがあるかと思います。
軽いものでは、ざっくりとした仕様の説明資料を渡されて、「これ、何日くらいでできそう？」と聞かれるパターンです。

ネットで見積もりについて調べるといろいろな手法が出てきますが、自分はそれらの手法を学んでから見積もりしていたわけではなく、最初は何となくで見積もりしていました。

それでも慣れてくるとそれなりの精度の見積もりが出せるようになってきているかと思いますが、見積もり経験のないメンバーに見積もりの方法を説明しようとすると、なかなか簡単には説明できないところがあります。

というわけで、いつも自分が見積もりを出すときの基本的な流れを振り返ってみたいと思います。
見積もり初心者の方々に、参考にして頂ければ幸いです。

要件
---
具体例を挙げたほうが分かりやすいと思うので、以下の簡単なスタンドアローンの売上管理システムを例として進めます。

・売上の追加・変更・削除を可能とする。
・売上を月ごとに一覧表示する。
・月に一度、バックグラウンドで売上を日ごとに集計し、CSVファイルに保存する。
・Windows10で動作するアプリケーション。
・言語はC#。
・データは同マシン内のPostgreSQLで保存する。

![見積り例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/7fdc380c-d365-786c-30fa-b88e27217074.png)

機能の抽出
---
まずは、要件から具体的な機能を抽出します。
単純に画面や機能をリストアップします。

![見積り1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/67713214-843d-dac5-f499-1ea0483b74c9.png)

ここは特に注意点はありませんが、最初に与えられた要件が漏れなく入れることだけ注意します。
口頭やメールなどで細々とした情報が入ることもありますので、それらもできるだけ入れてしまいます。

機能の細分化
---
次に、なるべく実装をイメージして細かく細分化します。

例えば「保存」の処理は、追加と変更でまったく実装が異なるケースもありますので、そのようなケースでは追加と変更は別項目にしたほうがよいかと思います。

また、新規システムの場合、基本的（共通的）な部分も加味すべきでしょう。

例えば、DB環境の構築、DBへの接続やコマンド発行部分を実装するのに工数が必要かもしれません。
また、バックグラウンド処理を起動する手法についても検討が必要かもしれません。

それらを踏まえて、機能を細分化します。

![見積り2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/cd527c8d-5606-5578-1f7a-e68add04d189.png)

ここでなるべく実装のイメージに沿って細分化することが、見積もりの精度を上げることにつながります。
周りに経験者がいれば、話を聞くことも有効でしょう。

作業工程、納品物、その他作業などの確認
---
次に、見積もり範疇の作業工程、納品物を確認します。
例えば、担当の工程が「詳細設計、実装、テスト」までだとすると、それらを見積もりの列に追加します。

また、納品物、その他作業を確認します。
納品物が「設計書、ソース、テスト手順書、テスト結果」などであれば上記工程内で一緒に見積もりますが、そこに含まれない納品物や作業がある場合、別行に追加します。
（操作マニュアル作成や、インストール作業など。）

それらを踏まえて、以下のような一覧にします。
これで見積もりの準備が完了です。

![見積り3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/e885eabd-64d2-c23b-1b79-71f2370db4d7.png)

概算見積もり
---
まずは、俗に言うKKD法（勘と経験と度胸）で入れてしまいます。
過去に経験したことのあるシステムのうち、なるべく似たようなシステムを思い返しつつ、どれくらいで終わりそうかをざっくり入れていきます。

![見積り4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/43913da8-9eb2-6dd1-8663-e4f2cca1ee07.png)

１つ１つ細かく考えながら入れていっても途中で見積もりがずれてくる（例えば、同じような機能なのに、最初のほうは3人日にしてたのに、最後のほうは5人日になってる・・・とか）ことがあるので、まずは全体を眺めてざっくり入れます。

この時は、まだ細かいところまで考慮せずに出しますので、まずは「普通ならこれだけあれば間違いなく終わるだろう」という多めの工数を入れておきます。

詳細設計やテストが不要そうな箇所は見積もりから除外しています。

もう少しマシな見積もり
---
これだけではあまり精度がよくないので、もう少し細かく見直ししていきます。
自身の経験に加えて、過去のプロジェクト情報を参照したり、実装イメージを思い浮かべ、それらを加味して補正していきます。

例えば、過去に類似システムのプロジェクト経験があり、知識を流用できそうであれば、そのぶんを考慮して工数を減らします。

あるいは、バックグランド起動の実装に思ったより苦労した経験があれば、そのぶんを加味して工数を増やします。

ファイル保存などで特殊なミドルウェアなどを使用する必要がある場合など、リスクが想定される場合は、そのぶん工数を増やします。
（ミドルウェアの仕様書などがあれば、確認したほうがよいでしょう。ミドルウェアの仕様が複雑であれば、それを確認する工数も加味します。）

![見積り5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/0a683443-41e7-3bac-05c6-556c61218bac.png)

このとき、想定している前提条件や懸念がある場合、なるべく備考に記載するようにしています。
想定と違って見積もりがずれた場合、相談させてもらう材料にもなりえますので。

もっとマシな見積もり
---
システムが大規模であったり、未経験の要素が多い場合は、少しのずれが大きな影響を与えることになりますので、少しでも精度を上げたいところです。
ここから精度を上げる方法はまちまちかと思いますが、実際にやったことがあることをいくつか列挙します。

・経験者に話を聞く。
・顧客にも情報を聞き、可能であれば有識者との打ち合わせを行ってもらう。
・ネットなどで情報を集め、少しでも具体的な実装イメージを掴む。
・時間があれば、リスクがありそうな箇所を仮実装・動作確認してみる。

その他の手法
---
自分がいつも見積もりする時の基本的な流れは以上ですが、見積もりの手法はいろいろとあるようです。

・類推見積もり（トップダウン見積もり）
　過去の事例や経験、実績から類推する手法

・係数モデル見積もり（パラメトリック見積もり）
　各機能の要件ごとに基準値（重みなど）を設定し、積算していく手法。

・ボトムアップ見積もり
　作業単位を細分化して、それぞれの工数を足し合わせていく手法。

・2点見積もり
　最も楽観的なケースと、悲観的なケースの間を取る手法。

自分の手法は、上記に当てはめると
「ボトムアップ見積もり」と「類推見積もり」の組み合わせ
という感じになるのでしょうか。

上記の手法の中にもさらにいくつかの細かい分類があるようですので、より精度を高めたい場合は取り入れるとよいかもしれません。

ここからは、やればやるほど（時間をかければかけるほど）精度は上がると思いますが、キリがないとも言えますし、延々と数字をいじくるだけになってしまうこともあります。
見積もりにどれくらい時間をかけられるのか、どれほどの精度が求められているのか、などを考慮してゴールを決めましょう。

まとめ
---
とりあえず最低限やっていることをざっと整理しました。
全体を通して注意しているのは、

・要件を漏れなく入れ込む
・なるべく作業の具体的なイメージを掴み、細分化する
・特殊な要件がある場合、リスクを加味する

といったところでしょうか。

結局は経験に頼って出しているところが大きいですが・・・少なくとも全部ひっくるめて直感的に「〇〇日！」と出すよりはかなりマシな、説得力のあるものになると思います。

補足
---
最後に、過去に見積もりが大きくずれることとなった要因を列挙します。
何かの参考になれば。。。

・未経験のWEBアプリケーション開発にて、開発環境の構築やフレームワークの理解に時間がかかった。
　→未経験の言語、フレームワーク、ミドルウェアを使用する場合は、できる限り事前に具体的なイメージを掴んでおきたいところです。このあたりはやはり経験がものをいう領域でしょう。

・すでに運用しているシステムの改造案件だったが、既存の処理が非常に煩雑で、調査・修正に時間がかかった。
　→既存からの改造は要注意ですね。
　　できれば事前にソースコードを入手したり、前回開発者がいれば話を聞くなどし、なるべくリスクを減らしたいところです。

・単体テストの結果をすべて手書きで残す必要があり、印刷・手書きに時間がかかった。
　→業務によっては、特殊な慣例や法律などがあり、予想外の作業を強いられることがあります。
　　初めて参入する業界では、そのしきたりなどにも注意が必要かもしれません。