原文連結:プログラミングで一番難しいのは「見積もり」だと思う - Qiita
在進行程式開發之前,通常會需要經歷更重要的「工時評估」。實際在開發時,也經常會被 PM 問到「這功能需要多久時間?這個 BUG 多久可以修好?」等情況,一開始可能會不知道該如何做評估,或不小心給出太長或太短的工時。
然而,這項能力是必須練習的,一方面與「成本估算」有關,另一方面也是「自我保護」,透過動態的修正,使估算工時的過程更加準確。
以下正文開始。
前言
在程式設計中,我認為最難的部分之一就是「估算成本」。每當收到程式設計的需求時,第一個問題總是「大概要花多長時間完成?」。在嚴格的情況下,可能會問「幾天能夠交付?」(不如說這或許是常態)。面對全新的案子,通常會藉由過去的所有經驗,來預測所需時間,盡可能將任務分解並估算時間,卻或許總是感到不安。應該有許多人對估算成本感到困難與不安,希望透過這篇文章,分享自己對估算相關的知識和經驗。
「估算」一詞具有多重含義,但本文中想表達的是「估算從開始到產品發布所需的時間」到「估算完成特定功能所需的時間」這個範疇的估算。
為什麼需要估算?
之所以需要進行估算,理由有許多個。
其中一個是為了投資判斷。需要計算開發該產品或功能所需的金錢成本,並判斷是否能夠獲得相應的價值,因此必須估算時間。如果回答是「我不知道需要多長時間,直到完成為止」,那根本無法開始開發。
此外,如果能夠事先知道時間,也能確定該何時開始準備市場行銷活動,或是否應該增加人力資源。如果不知道需要多長時間和成本,則無法制定其他計劃。出於這些重要原因,我們必須能夠對自己的工作進行估算。
為什麼估算很困難
為什麼估算如此困難呢?原因在於,有太多的不確定性。
- 對於從未嘗試過的工作,無法知道需要多少時間
- 可能會出現意料之外的任務
- 不知道學習使用的框架或技術需要多長時間
- 可能會遇到困難點被卡住
- 不知道發現和修復錯誤需要多長時間
- 在團隊開發中,無法知道其他人的開發速度,也不知道自己將負責什麼
應該還有各種原因。事實上,很少有人能在一開始就完全理解即將開發的目標。估算是一個充滿不確定性的過程,因此讓人感到卻步,然而估算仍是必要的過程,不得不去執行。
造成估算困難的因素
雖然上述提到,由於存在太多不確定性,使得估算變得困難。即使如此,透過將任務分解,動用過去的知識,建立現實性的假設,仍然能夠進行估算。然而,還有另一個使估算變得更困難的因素。
這個因素是「估算的日期即為截止日期」。
如果對上司說出「可能需要一個星期完成」,那即使到星期五晚上,也必須加班到深夜以確保完成。假如有截止日期,那麼無論如何都必須在該期限內完成。
基於這個原因,即使估算大約需要一個星期的時間,也不能輕易說出「可以在一個星期內完成」。
由於存在高度的不確定性,我們無法得出「一個星期即可完成」的結論。估算只能得出「一個星期完成的可能性最高,但可能存在 50~200% 幅度的差異」。
因此我認為,實際估算的情況和追求的估算結果(截止日期)之間的差異,是造成估算困難的原因。
估算方法
估算的困難性,源自於不確定性和認知不一致,面對這些問題,該如何抱持誠實的心態來應對呢?
首先介紹應對不確定性的方法,這是在敏捷開發中使用的「故事點數和速度」估算方法。
故事點數與速度
Story Point 故事點數
由於任務存在不確定性,很難做出絕對性的評估。因此,使用相對評估來進行估算,即為故事點數。
若將工作 A 估算為 5 點時,可能需要花兩倍時間的工作 B,則會被估算為 10 點。不到工作 B 的難度,但比工作 A 困難的工作 C,則可能被估算為 7 點。差不多是這樣的概念。
人們普遍認為,相對評估比絕對評估更準確。要估算遠處建築物的高度很困難,但如果是估算相對於隔壁的小建築物會大多少倍,則任何人都能做到。
透過分配點數給已識別的任務,最後總點數即為該產品或功能完成的估計值。
Velocity 速度
光是擁有故事點數這些數字,並不具有實際意義。估算的目的,是為了做出決策或用於其他計劃,因此必須將其轉換為「時間」。
速度是實現這一點的關鍵。
實際執行任務,並測量每一點所需的時間。
假設估算一個功能開發,需要的故事點數共 80 點,而完成一個 8 點的任務需要 1 天,即可推測功能開發需要 10 天的時間。
Burn down chart 燒盡圖
將「總故事點數」、「已完成的故事點數」和「剩餘的故事點數」,按照時間順序繪製成折線圖,即稱為燒盡圖。
在順利進行的專案中,剩餘點數將形成一條向下的斜線,當該斜線延伸到 x 軸時,代表專案預計完成日期。
在確認或共享進度時,透過將資訊可視化,能夠一目瞭然的燒盡圖非常重要。
兼顧不確定性的估算
上述提到估算變得困難的原因,是「估算結果」變成「截止日期」。
考慮到估算可能成為「截止日期」,為了自我保護,可能會犧牲估算的準確性,以提供過多的緩衝時間。即使認為一個工作需要 1 周完成,為了安全起見,可能會說需要 2 周,但這樣真的是誠實的回答嗎?
改變傳達方式也是一種方法。
與其說出「完成需要 2 周的時間」,不如傳達「估計整體完成需要 4 至 10 天。預計前 3 天可能完成這些進度。」並共享燒盡圖以確認當前進度。我認為這種方式,能更確實傳達確切的資訊,並承認估算的不確定性。更重要的是,估算應該時常進行修正。在專案初期,認知到估算充滿不確定性,並隨著知識的累積重新進行估算,即可與決策者共享更精確的估算結果。
重新估算
當一個任務估計需要 2 天,最終卻耗時 3 天的情況,我們經常會思考「為什麼沒有按照預期的進行?」。接下來的任務,為了趕上進度表,我們會付出更多的「努力」。當進度不如時間表的預期時,為提升速度付出的「努力」,通常會付出更大的代價。因為時間緊迫,將導致產出不穩定的程式碼,即使發現錯誤也可能被忽略,或即使想出有價值的功能,也可能被忽視。
但我們並不想做這樣的「努力」。如此一來,我們反而應該思考「為什麼把需要費時 2 天的任務錯估為 3 天?」。修改當初的估算,根據這次花費比預計多 1.5 倍時間的任務,將與其類似的任務的故事點數乘以 1.5 倍重新估算。透過修正的步驟,能夠使估算更加準確。
最後
在這次分享中,介紹對於估計的觀念,以及在敏捷開發中使用的故事點數估計方法。
當然,實際情況會因讀者所處環境而有所差異,本文提到的方法和思維方式,可能也不適用於所有情況,希望能提供作為參考。
15th鐵人賽目錄傳送門:https://ithelp.ithome.com.tw/users/20135558/ironman/6290