出来らぁっ！と言わない為の工数見積もり術

SC（非公式） Advent Calendar 2018 の19日目になります。
…お前、タイムリープしてね？ という突っ込みは穴を埋めた功績で帳消しです。私には効きません。

【追記】
書いていて前置きが長くなっちゃったので、すっ飛ばして本編のみ見たい人は
[KKDで後からキツくならない見積もり術](https://qiita.com/wryu/private/96a11ded58cf62034e10#kkd%E3%81%A7%E5%BE%8C%E3%81%8B%E3%82%89%E3%82%AD%E3%83%84%E3%81%8F%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84%E8%A6%8B%E7%A9%8D%E3%82%82%E3%82%8A%E8%A1%93)
のセクションからどうぞ。

# はじめに

突然ですが皆さん、こんな経験はありませんでしょうか。

- - -
いつも通り作業をしていると、突然PMやPLが隣に腰かけ、

>Aさん：○○さん、こんな感じの画面作るならどれくらいかかりそう？

と何気なく問いかけてくる。

　
とりあえずこちらから開発言語とかフレームワークを訊いて、簡単に機能要件を訊き出した後、

>○○さん(あなた)：...であればxxxに時間がかかりそうなので、
　　　　　　　　作業バッファも入れて5人日くらいですかねぇ
　　　　　　　　(できれば+1.5人日バッファ欲しいけど)

と、天井に目をやりながらぼんやり答えると

>Aさん：う～ん、なるほどねぇ、ありがとう。

そう言い残すと質問者は口を結んだまま、そういうものか、という顔で去っていった。



　
幾日か幾月か後、開発現場にて...
　

>Aさん：この前見積もって貰った画面の開発だけど、○○さんに類似の画面やって貰うから。

>○○さん(あなた)：分かりました。ちなみにどう違うんですか？


>Aさん：えーっと、チェック項目が10個くらいとcsvアップロード機能が増えた感じね。
　　　  基本は同じ作りだからバッファ分使って5人日でよろしくね。　


　

***○○さん(あなた)：えっ、５人日でそんな画面の開発を！？***

　

![dekira.png](https://qiita-image-store.s3.amazonaws.com/0/131674/8953c9eb-fece-63c9-ae1f-83cbdcfbefd8.png)
(元ネタと発言順違うけどゆるして)

　
・・・



- - --

  
こんな感じで
「作業工数の見積を答えたはいいものの、なんやかんやで後から痛い目に遭った...」
という経験。あると思います。


ということで、本稿ではこういった見積ズレの悲劇がなぜ起こるのか、
そしてどうすれば未然に防げるのかを考察していきたいと思います。



※１ 先のような例で、その後気合で乗り切ったのか、はたまた崩壊したのか、
　　 といったアフターケアの話は取り扱いません
※２ なお、この記事では受注請負開発でウォーターフォールに則って開発する事を
　　 前提として記述しておりますのでご了承下さい


# なぜ見積のズレが出やすいのか

早速ですが、そもそも何故工数の見積もり作業は難しく、
開発時に必要な工数との乖離が発生してしまうのでしょうか。

結論から言いますと、仕事を受発注する際の予算請求を行う為に、
**見積もりを早い段階で行う事が一因といわれています。**

IPA(情報処理推進機構）が見積についてのレポート記事を上げていますので
そちらを参考/出典として考察してみます。
以下の図１を見て下さい。

※時間軸ではなくて規模と情報量を軸に図が作成されている為、ちょっと分かり辛いのですが
　基本的に横軸の情報量はプロジェクトのフェーズ/実施時間が進むについて増えていきますので
　横軸が時間軸、青線に囲まれた黒字達が「見積の判断材料」と捉えて差支えないかと思います

![image.png](https://qiita-image-store.s3.amazonaws.com/0/131674/12831623-f9b0-19ed-08cf-289b1034cd98.png)
>図１ 出典) [エンタプライズ系事業/見積もり手法](https://www.ipa.go.jp/sec/softwareengineering/std/ent01-c.html)


原点に近い初期の見積もり段階では類似システムの規模感(経験)や必要なデータ項目といった
既にあるもの、システムに欠かせないデータ項目等を判断材料に見積をすることになります。
※経費清算のシステムならば「伝票」「料金」など

当然ながら生のソース、要求仕様と比べると参考情報が少ない/確証度が低い為、
赤矢印で図示されている通り、見積と実体で生じる誤差の範囲も大きくなってしまうのです。

この**時間を経るごとに確証度が高い情報が揃ってくる**という理屈は見積だけでなく、
実際の作業を進めていく際にも当てはまります。

発注する側、いわゆるお客さんが出す仕様/要望についても時間を経るごとに具体的になる為、
「当初予定していた機能だけでは要求を実現できない」だとか
「こちらの画面にある機能が便利なので、他の画面にも欲しい」というように
実現したい機能/要求が膨らんできます。

そうして誤差が生じた結果、
「見積時に多めに盛りすぎて実際の作業に余裕ができた」という結果なら良いのですが
「見積時に少なく見積もりすぎて実際の作業工数がオーバー気味になった」という風になると
余裕がなくなる ⇒ できらぁ！ という事態につながる訳ですね。

### じゃあどうしたらいいのか

正直、見積の初期段階でブレが出るのは仕方のない事だと思います。
限られた情報から予想出来る事って限界ありますからね。

なので

- 後々ブレが出る事を大前提として、受注/発注側が合意する
- そのうえで工数(お金/期限)を増減できるような取り決めにしておく

って事ができたら良いんだと思います。

一介のエンジニアでは簡単にこの辺の事情には首を突っ込めないので
正直、他人事感ありますけどね...。

ちなみにIPA(情報処理機構)も同様に仕方ない、って考えてるようで

>不明確な部分があるとどうしても実際にできあがるものから比べて，
見積りの「ぶれ」が出てしまうことは避けようがありません。
　　　　　　　　　　　　　　　(中略)
解決策は「わからないものはわからないもの」としてリストアップし、
さらには不確実性の評価（どの程度のぶれ幅になるのか）を行って関係者の間で共有しておき
適切なタイミングで見直すことが必要です。
特定された「わからないもの」は，見積りが確定していない範囲として
ユーザとベンダとで相互に認識を合わせておき、確定するまでモニタして双方でコントロールすることが
見積りの妥当性を確保するための基本的な対策となります。
不確実なもののコントロールは関係者すべての協力が必要ですが，特にユーザが最終的な判断の鍵を握っているので
これらの活動においてユーザがリードすることが望まれます。

って言ってました。
出典) [ソフトウェア開発見積りガイドブック](https://www.ipa.go.jp/sec/publish/tn05-001.html)


# 作業工数の見積方法
では本題の、もう少し段階が進んだ「現場のエンジニア/PL等による作業工数の見積」に焦点を当てましょう。

まず、作業工数の見積のやり方は幾らかあると思いますが、大別して

- 類似/既存コードのStep数/ファンクションポイントを計上し、さらに計上した値に
  変数を四則演算することで補正した値を規模とする

- 見積者(＝大体ベテランのエンジニア)がK(経験)、K(勘)、D(度胸)の三要素を以て
  直観で見積もる

というやり方に分かれてい(ると思い)ます。



一見すると前者の、Step数/ファンクションポイントに基づいた見積法の方が客観的な値であり
補正をかけている事から精度が高いように見えますが、実は案外アテにならなかったりします。
※プログラムステップ法(LOC法)、ファンクションポイント法などが該当します

というのもLOC法はコードの行数を基にする為、冗長な書き方やｷﾂｷﾂに圧縮した書き方をすればいくらでも調整できますし、
ファンクションポイント法はデータ/ファイルに対するCRUD(作成/参照/更新/削除)によって
機械的にポイントが割り振られていく為、処理の複雑さが考慮されていません。
さらに、オブジェクト指向の再利用性や抽象化といった事も考慮されていませんので
昨今のオブジェクト指向言語を利用したアプリケーション開発に適用するとブレやすくなります。


　
　
後者のKKDは実施する人依存ですので、それこそブレ幅無限大＆リスキーでもあるのですが
開発に利用する技術的な要素、仕様の複雑度、潜在的な非機能要件、開発人員の習熟度
といった現実的な要素を考慮して見積もる事ができます。

つまり勘や度胸と言った一見アレな要素が入りつつも、ちゃんとポイントポイントで抑えていれば、
これ以上無い程正確、かつしっかりとした根拠のある見積になると言えます。



タイトルや冒頭の例に表れているように、今回私が書きたいのは、KKDでいかに辛い目に遭わないように見積もるか、という所です。

なのでLOC法やファンクションポイント法の話はもうしません！ハイ終了！！


# KKDで後からキツくならない見積もり術

では、実際にKKDで作業工数を見積もる際に、抑えておきたいポイントとは何でしょうか。
先程挙げた事項も含め、表にしてみました。
重要/影響度が高い物ほど、注意深く見積もった方がよい、というカンジです。
※項目ごとの説明は横に長くなっちゃうので後述

|No.| 考慮すべき事項    | 重要/影響度(最大★5)  |
|:-:|:-----------------|:-------------------:|
|1| 開発言語          |★★★| 
|2| 使用データベース   |★★| 
|3| 開発フレームワーク |★★★★|
|4| ORマッパー　      |★★★|  
|5| 仕様の複雑さ      |★★★★★ | 
|6| 非機能要件        |★| 
|7| 作業要員の習熟度   |★★★|
|8| 見積者の習熟度    |★★★| 

①開発言語
⇒サーバー/クライアントサイドに適した言語を使い分けていれば、言語自体の差はあまりないと思います。
　(Javaだとこの要件は実現できません！とかそういうやつ)
　ただし「めっちゃ古いシステムの保守なので.NetFramework1.0のVBでよろしく☆彡」というような
　当該言語の旧バージョンで頑張らなきゃいけない:poop:な状況になると、概してコーディング量が増え
　回り道を余儀なくされる為、時間がかかる＝工数が膨れます。

　
②データベース
⇒業務アプリなのにリレーショナルDBではなく階層DBやKVSでごり押す等、
　運用面で無理をしていなければ、DBソフト毎にそこまで差はないんじゃないでしょうか。(知らないだけ
　「高いけどやっぱり性能は出るのはOracleよね」とか「お金をかけたくないからMySQLにする」とか
　作業時間よりも、むしろ予算との相関性が強い気がします。

　
③開発フレームワーク
⇒個人的には開発言語よりもこちらの方が重要だと思っています。
　フロントアプリならVue.js？React？とかJavaのサーバーサイドならSpring？Struts?とかとか。
　そもそもMVCにするの？サーブレットとかコードビハインド？とかとかとか。
　フレームワーク毎の特徴/メリデメを考慮しないと、フレームワーク自体の脆弱性の対応に気を遣ったり
　アプリの規模に見合わず、"開発する事" 自体にコストがかかりすぎたり、
　作り終えたはいいけど、できた物がごちゃごちゃで保守がし辛すぎて死ぬ～なんてことになります。

　また、開発言語やORマッパーにも言えることですが、作業要員の当該フレームワークの習熟度によって
　大いに開発効率が変わってきますので、かなり重要度高といえるでしょう。

　
④ORマッパー
⇒アプリ上のDBへの処理/アクセスを担う部分ですが、モノによっては同じSQLを流用しているように見えても
　パラメーターではなくSQLを直に組み上げる事になる為、毎度実行計画が変わって安定しない～とか、
　後からSQL文を変更しようとするたびにアプリ全体をビルド(コンパイル)し直さなきゃいけない～とかとか、
　開発時はもちろん、稼働後のパフォーマンス/保守性に影響しますので注意深く見た方が良いでしょう。

　
⑤仕様の複雑さ
⇒まぁこれが具体的に分かればそもそも苦労はしないよね、って話ですが、
　"仕様の複雑さ" というのをより具体的にするならば

- 全般⇒他機能/画面との連携、違うアプリやシステムとの相関性
- 画面⇒入力項目の多さ、データに対するチェックの多さ、見栄え上の要件(滑らかさ等)
- 　　　マルチプラットフォーム対応、レスポンシブデザインなど
- バッチ⇒データに応じた処理の分岐、データ変換の必要性、関係するDB上のテーブルの多さ

　とかが該当すると思います。これらがモリモリに詰め込まれた仕様だと要注意ですね。
　

⑥非機能要件
⇒そもそも他の要素を考慮する際にも、パフォーマンスや保守性といった非機能要件を考慮するので
　漠然と「"非機能要件" それ自体を考慮する」というのも難しいのですが、個人的には
　発注側やエンドユーザーのITリテラシーやアプリへの理解度、画面内の分かりやすいUI設計、
　動線を意識した項目配置などなど、人間の感覚的なところに近い要素が該当すると考えています。
　(子供向けのWebサイトだったら難しい言葉は使わずひらがなで表記～などなど)

　こうした非機能要件は開発作業にどれだけ影響するか、また重要視したところでアプリの使い勝手や
　顧客満足度に最終的にどれだけ影響するのか、ということが数値で現れ辛いので判断が難しいところです。

　突き詰めると「設計者/開発者がいかにユーザー目線になれるか」という終わりなき戦いだと思うので
　よほど発注側から要件/仕様として明確化されたものでない限り、受注者としてはビジネスライクで
　「+αでやれたらいいよね」位で、考慮すべき要素から切り捨てちゃうのが現実的かなって気がします。

　
⑦作業要員の習熟度
⇒これも重要です。プロジェクト/アプリの規模によって動員される人数は変わりますので
　そもそも考慮すること自体難しかったりするのですが、「新人のOJTを兼ねて若手が大半を占める」とか
　「単価の安い外国のIT企業へアウトソーシングする」となるとバッファを大目に設けるといった策を
　講じておかなければ不安が残りますよね。
　逆も然りで「プロフェッショナル人材が集まってるのにやたら長い期間を要求～」
　となるとお金が高くつきますから、発注側は納得してくれないでしょうし。
　[働きアリの法則](https://ja.wikipedia.org/wiki/%E5%83%8D%E3%81%8D%E3%82%A2%E3%83%AA%E3%81%AE%E6%B3%95%E5%89%87)なんてものもありますし、仕事がデキる人用の歯ごたえあるタスク、
　あんまり仕事がデキない人用のやわらかタスクを、意識的に設けて見積もるとうまくいく気がします。
　
⑧見積者の習熟度
⇒見落としがちですがこれも重要です。
　大体の場合で
   > 見積もりをする(orさせられる)人 ＝ 仕事がデキる人、技術的に明るい人

  という図式が成り立つ場合が多い為、無意識的に「自分ならこのくらいでできる」という数字になったり、
　「デキない人がどれくらいかかるかわからんから、とりあえず大目に見積もるか」なんてことになります。
　後者なら工数が余る方向なのでよいですが、前者の場合は陥らないように気を付けないといけません。
　できれば見積人は作業要員のレベル感を、過去の仕事ぶりや聞き込み等で把握しておくとよいと思います。

　ただし、年功序列や職務に対して縦割り的な組織色が強い場合は

> 見積もりをする(orさせられる)人 ＝ 一線を退いたベテラン、そもそも技術全然知らない人(営業さんとか)

  というパターンもあるので、その場合はできるだけ技術に明るい人が見積もりのサポートをするようにしましょう。

　

長くなりましたが、私が考えるKKDで後からキツくならない見積もり術とは
**見積もりの際に、即答/即決 or 適当に行わず、上記の要素をしっかりと考慮すること**
だと思います。


# 終わりに
いかがでしたでしょうか。若輩者の浅知恵かもしれませんが、私がいままで経験したプロジェクトから
「こうすればもっといい見積だったんじゃないの」という思いを整理して、ずらっと書き連ねてみました。

「これは違うっしょ」とか「これを考慮できたらもっといいよね」といったご意見等がありましたら
コメントよろしくお願いいたします:bow_tone1: