软件开发工期估算系列(1)——正確な見積もりはデスマーチ・プロジェクトを救うか?

【转载按】

日本软件开发工期估算的系列文章,文中提出一个观点:“软件开发技术者的最高能力是——工期估算”。

姑且不论这种观点是否正确,工期估算确实是项目开发中的一个比较大的难题,

如何使用科学的方法最大可能的合理估算,是值得研究的一个课题。

 

【原文】

 

 

http://monoist.atmarkit.co.jp/mn/articles/1105/24/news002.html

 

 

正確な見積もりはデスマーチ・プロジェクトを救うか?

 

「ソフトウェア技術者の最高の能力は、見積もりだ!」――今回から“見積もり”をテーマにした新シリーズ「見積もり:ソフトウェア技術者の最高の能力」をお届け。今回は、ソフトウェア開発で正確な見積もりが必要とされる理由について紹介する。

[山浦恒央 東海大学 大学院 組込み技術研究科 准教授(工学博士), @IT MONOist]

今回から新シリーズとして、「見積もり」を取り上げます。見積もりは、これまでお届けしてきた“ソフトウェア・メトリクス”以上に大きなテーマであり、ソフトウェア工学における最重要課題の1つといえます。

 ソフトウェアの開発は、可能性を追求する「科学(science)」ではなく、採算性を重視する「工学(engineering)」です。プロジェクトでソフトウェアを開発する場合、“何人のエンジニアを何カ月投入すればよいか”を見積もることは非常に重要ですが、実際、ほとんどの組織でこうした見積もりがきちんとできていません。この瞬間にも、世界中で何十万ものソフトウェア開発プロジェクトが走っていることでしょうが、その中の約半数が途中打ち切りになるはずです。厳しい言い方をしましたが、実際、プロジェクトの途中打ち切りの原因の約48%は、「楽観的な見積もり」によるものです……。

 今回の見積もり・シリーズでは、「見積もりの目的(正確に見積もるだけでは不十分)」「見積もりの具体的な方法(精度を上げるため、少なくとも2つ以上の方法で見積もる必要がある)」「見積もりの応用(見積もり値に合わせる制御と再見積もり)」「見積もりの調整(状況に応じて開発量とスケジュールを再見積もりしなければならない)」について、具体的に解説していきます。

なぜ、見積もるのか?

 私が崇拝する先輩エンジニアは、

ソフトウェア技術者の最高の能力は、見積もりだ!


と1日に10回は言っていました。ソフトウェアの開発経験を重ねるにつれて、先輩のこの言葉を痛感する機会が増え、今では、私が同じことを1時間に10回繰り返しています。

 ソフトウェア開発における見積もりとは、顧客から受注したシステムの概要をベースに、「プログラムの規模(ステップ数)」「開発期間」「投入人月(コスト)」を予測することです。

 なぜ、見積もりをするのか? ――この問いに対し、技術者として常識的な答えは、「(1)開発コストの算出(2)プロジェクトの立ち上げ(3)出荷スケジュールの策定の3つをできるだけ正確に行うため」です。以降で、これら3つにおいて正確な見積もりが必要とされる理由を見ていきましょう。

(1)開発コストの算出

 発注者と開発契約を結ぶとき、必要コストを見積もり、そこに利益を乗せて、最終金額を計算します。

 自動車、飛行機、ビルなど、手で触れられる工業製品・建造物を作る場合のコスト計算では、材料費と人件費の両方を考慮しなければならず、複雑な計算が必要です。一方、ソフトウェア開発のコスト計算では、正確に算出しようとすると、他の工業製品と同様、開発で使うPCなどのハードウェア、ツールなどのソフトウェア、通信回線などの使用料やレンタル料に加え、人件費を計算しなければなりません。

 しかし、実際、ソフトウェア開発の場合は、人件費が圧倒的に多く、開発環境で使用するハードウェアやソフトウェアのコストを無視して計算する場合がほとんどです。小説を書く場合、原稿用紙、ペン、インクのコストは、人件費に比べて圧倒的に小さいので、無視するのと同じです(この意味でも、ソフトウェア開発は小説の執筆と酷似しています)。

 基本的にソフトウェア開発のコストは、人件費が100%と考えて構いません。人数×月数の人月はコストに比例し、日本では1人月100万円前後で見積もることが多いようです。アメリカでも1人月1万ドルで計算します(インドや中国では、15~30万円なので、日本とアメリカは世界で最もソフトウェアの開発コストが高い国といえます)。

 ソフトウェア技術者の生産性として、生産したソースコードの行数を開発月数で割った値を使用するのが一般的です。すなわち、コメント行を含まないソースコード行数を、仕様書作成、モジュール設計、コーディング、デバッグという全ソフトウェア開発工程に掛かった月数で割り算します。新規開発の場合、1人のエンジニアが1カ月で生産するプログラム行数は、1000ステップが平均的でしょう(この値は、40年前から不変ですし、40年後も変わらないと思います)。つまり、プログラムの行数が分かれば、1000ステップで割って人月を計算でき、人月に100万円を乗ずれば、いくらコストが掛かったかを簡単に算出できます。

 人月計算の見積もりを間違えると、利益が出ないばかりでなく、会社が倒産するほどの赤字を抱え込むことになります。いろいろな会社のソフトウェア開発者が集まる懇親会では、お酒が入ってリラックスするにしたがい、生々しい話が飛び交います。例えば、

去年、ウチの会社で、データのコンバージョンを請け負ったときなんだけれど、ツールを使えば自動変換できると見込んで、6人で6カ月、36人月と見積もって、4000万円で契約したところ、実際にやってみたら自動変換できなくて、結局、20人が人力で変換して12カ月も掛かってしまったらしい。20人×12カ月=240人月なんで、2億円以上の大赤字……。


いやいや、ウチの会社でも同じだよ。この前なんか……。


と見積もりミスの話題は絶えません。

 利益は、多くてもコストの30%ぐらいでしょうが、赤字幅には際限がありません。大赤字プロジェクトが1つあるだけで、100のプロジェクトで苦労して上げた利益を一瞬で食いつぶしてしまいます。正確な見積もりは会社の存続にかかわる“超”重要課題です。

(2)プロジェクトの立ち上げ

 プロジェクトを立ち上げるとき、あちこちからエンジニアを集めてこなければなりません。何人のエンジニアを何カ月拘束するのかが明らかでないと、上層部に技術者を要求できません。

 プロジェクトの立ち上げには、正確な見積もりが不可欠なのですが、ここに“見積もりのパラドックス”があります。何人を何カ月拘束するかを正確に見積もるには、仕様がある程度固まっている必要がありますが、仕様を定義するには、プロジェクトを立ち上げて仕様を定義・検討しなければならないのです。

 従って、極端な場合、プロジェクトマネージャーは、発注側の担当者と立ち話をして、「高輪キャンパスの図書館と、湘南キャンパスの図書館を統合して、Web経由で検索や操作できるようにしてほしいんだけど」と言われ、これだけの情報から、見積もりをしなければならないこともあります。こんな状況では、見積もりが不正確なのは当たり前です。

(3)出荷スケジュールの策定

 「いつ出荷できるのか」、あるいは「いつまでに出荷しなければならないのか」といった出荷スケジュールを制御することは、組み込みソフトウェアのように、小さくて安い製品を大量に販売する場合には、極めて重要な課題です。

 例えば、上記の「図書館統合とWeb検索」を細かく分析して、12人×12カ月=144人月でできると見積もったとします。この結果を発注者に提示したところ、「新学期から稼働させたいので、3月1日までに納入してほしい。なので、開発期間は12カ月ではなく9カ月でお願いしたい」と言われた場合、どうすればいいでしょう?

12人×12カ月=16人×9カ月


と計算して、「では、エンジニアを16人に増やして、9カ月で完成させます」と回答すると、その瞬間、プロジェクトは崩壊します(あるいは、数億円の赤字を確実に抱えることでしょう)。

 結論から言いますと、“スケジュールを25%短縮したいなら、エンジニアの数を2倍に増やさねばなりません(なぜ、そうなるのかの詳細は、本シリーズの後半で解説します)”。人月計算において、人数と月数は交換可能ではありません。人数と月数は、線形ではなく、以下のように、指数関数的な関係にあるのです(この原理も、後ほど触れます)。

12人×12カ月(144人月)=24人×9カ月(216人月)


デスマーチ・プロジェクトと見積もり

 以上が、正確な見積もりが必要とされる理由です。では、極めて高い精度で開発規模や開発期間を見積もることができれば、全ての問題は解決できるでしょうか? 答えは、もちろん「ノー」です。

 上記の「図書館統合とWeb検索」の開発で、プロジェクトマネージャーが12人×12カ月=144人月(1億4千万円)と見積もった値が、実際の値の±3%という極めて正確な見積もりであったとします。一方、発注側と受注側の上層部が日曜日の午後、ゴルフをしながら、

実は、例の図書館統合の件だけど、今、ウチはお金がないんで8千万円しか出せないんだ。それと、新学期から運用を開始したいんで、6カ月で完成させてほしい。


分かった、任せといてよ。今は、どこも財政難で大変だからなぁ。ウチのプロジェクトマネージャーにその条件で見積もりをさせるよ。


と勝手に話が進んでいたりします。もちろん、この「政治的見積もり」は絶対に守らねばなりません。プロジェクトマネージャーが正確に見積もった値、12人×12カ月=144人月(1億4千万円)は意味を持たず、何が何でも8千万円(80人月)のコスト、6カ月のスケジュールで開発しなければなりません。

 実際に必要な開発期間の半分しか割り当ててもらえないプロジェクトを「デスマーチ・プロジェクト」と言います。上記のプロジェクトは典型的なデスマーチです。デスマーチ・プロジェクトの無理難題の前では、正確な見積もりは予想外に無力なのです。

 デスマーチ・プロジェクトへの対処法は以下の3つがあります。

対処法(1):言われた条件をそのまま受け入れる

 しかし、実際、朝9時から終電の時間まで働き、土日も出勤して一生懸命コーディングしても、結局大幅に遅れ、品質も最悪の物しかできません。発注側と受注側は、確実に共倒れします。これは、過去40年間、人類が繰り返してきたことです。

対処法(2):提示された条件では開発不能なので、仕事を断る

 正確な見積もりを背景に、「このスケジュールではできません!」と上層部に主張しても、「工夫もしないで、出来ないなんて言うな!」とか、「そこを何とかするのが、プロジェクトマネージャーとしての君の責務だろ!?」と叱責され、結局は、無理難題を飲まされます。ほとんどのプロジェクトマネージャーは、こんな経験をしているのではないでしょうか?

 仮に、断ることに成功し、デスマーチ・プロジェクトを事前に回避できたとしても、「できない!」の一点張りで、単に断るのでは“子どもの使い”と同じです。また、断る=ビジネスチャンスの損失ですので、この対処は非常に悩ましい決断といえます。

対処法(3):相手の提示条件で、できる範囲の開発をし、発注側と受注側の双方が満足するような方策を探す

 3つの対処法の中でこれが最善策ですが、そのためには以下が必要です。

  1. 相手の提示条件に対し、説得力のあるデータを示して「ノー」と言うこと。提示された条件では開発が不可能であることを客観的に証明する必要がある。このためには、非常に高度な見積もり能力が不可欠
  2. 相手の条件内でできる作業を提案すること。このためには、開発規模を動的に変更できるようにしておく必要がある

 見積もりは、どんなに正確であっても単独では存在できません。特に、デスマーチ・プロジェクトと一緒に考える必要があり、「発注側と受注側の双方が満足する開発」を策定するために、見積もりを活用することが極めて重要です。



 次回は、「見積もりの基本と常識」について解説します。(次回に続く)

### 软件项目管理中的参数模型估算法 #### 方法概述 参数模型估算是指利用统计技术和数学建模方法,通过对历史数据的分析来构建用于预测未来项目的规模、成本或工期等关键因素的模型。这种方法依赖于识别并量化那些显著影响项目结果的因素作为输入变量[^2]。 对于软件项目而言,这类模型通常会考虑诸如代码行数(LOC)、功能点(FP)这样的度量单位以及其他可能影响开发过程的技术特性或团队效率指标。通过将当前项目的特征映射到已有的模式上,可以较为精确地估计出预期的工作量以及相应的时间安排和预算分配[^3]。 #### 应用实例 为了更好地理解如何实际运用这一技术,在这里提供一个简化版的应用场景: 假设某公司正在启动一个新的Web应用程序开发计划,并希望通过参数化方式对其所需的人力投入做出初步评估。此时可采取如下步骤操作: 1. **定义关键属性** 首先确定哪些方面会对整个流程构成主要挑战——比如界面设计复杂程度、后台逻辑处理强度或是数据库交互频率等等;同时也要考虑到外部约束条件如交付期限限制等因素的影响。 2. **搜集相关信息** 接着从过往完成过的相似案例里提取有用的数据片段,特别是有关最终产品大小(以千行计)、参与人员数量及其技能水平分布等方面的具体数值记录下来供后续参照使用。 3. **创建关联规则** 利用上述资料建立起两者间的联系表达式,即所谓的“估算方程”。例如,如果发现过去每增加一千行有效源码平均就需要额外花费大约0.8个人月去实现,则该比例就可以成为本次规划的重要参考依据之一。 4. **实施具体运算** 把新任务的各项设定填入之前制定好的框架内执行计算作业,从而获得大致的结果范围。假定预计总共有五万行待编写的新鲜代码等待加入现有平台之中,那么按照前述比率推算出来的理论耗时就应该是 \(50 \times 0.8=40\) 个人月。 5. **审核校正成果** 最终还需仔细审查所得结论是否合理可行,并据此作出必要的微调优化直至满意为止。值得注意的是,任何此类工具都存在固有限制性,因此务必保持谨慎态度对待其给出的意建议,不可盲目信赖而不顾现实情况的变化发展。 ```python def estimate_project_effort(code_lines, effort_per_kloc): """ Estimate the total project effort based on lines of code and historical data. Parameters: code_lines (int): Total estimated number of new lines to be written. effort_per_kloc (float): Effort required per thousand lines from past projects. Returns: float: Estimated person-months needed for the project. """ klocs = code_lines / 1000 return round(klocs * effort_per_kloc, 2) # Example usage with hypothetical values total_effort = estimate_project_effort(50000, 0.8) print(f"The estimated effort is {total_effort} person-months.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值