要怎麼估算需求需要多費多少時間完成,要怎麼讓 PM/PO 與 team 可以快速達成共識,要怎麼避免人事物的干擾因素,這篇文章說明了在 Scrum team 中估算的方式、時間、效益、參與人員等…即使不是使用 Scrum ,也可以依據這些概念來找到最適合您們團隊的估算方式。
前言
在軟體開發過程中,團隊往往會有一個疑問:「工時怎麼估才會較為準確?」對專案或產品的 owner 來說,這是他們衡量專案資源與時程很重要的一項資訊,然而實務上卻因此造成了許多問題。
許多開發人員總覺得 PM 根本是用 deadline 來回推工時的,他們根本不在乎時間內該 feature 是否能有品質的完成。「先求有,再求好」這句名言也因此在軟體產業流傳許久。
許多 PM 則總是覺得開發人員估工時都是灌水居多,平常看他們的工作狀況好像都在摸魚,看起來好像都是用業界流傳的估工時方式:「先估個 3 倍時間當 buffer。」
事實上工時的確是無法估到「絕對準確」的,但可以採用一些方式來估到「相對客觀」。因工時與需求的複雜度,往往呈現正相關,因此本文會先針對需求複雜度來說明目前常見的問題,提出一個建議的解決方案,以及解釋解決方案中諸多設計的目的。
Problems
- 開發人員的地雷
- PM:「這很簡單啊,應該不需要花太久時間就可以做出來吧?」
- PM 今天跟你說:「明天之前就是要交出來,先求有再求好。」
PM 後天跟你說:「為什麼程式的品質這麼差?」 - 已經 delay 的時候,其他同事:「你這怎麼需要花這麼久的時間?這有現成的 code 可以參考,這有做好的底層可以使用啊,你怎麼沒問我?」
- 其他同事:「這我只要一天,為什麼你要這麼多天?」
- PM:「這是 common sense 啊,需求即使沒提,你也應該知道這要做。」
- PM/PO 的地雷
- 內心OS:「為什麼這麼簡單的東西,要花這麼久的時間?」
- 內心OS:「為什麼都看到你們在逛 Facebook ,東西卻來不及做出來?」
- 內心OS:「為什麼做出來的東西品質這麼差?」
- 內心OS:「為什麼他上次一天就做出來,你要做這麼多天?」
- 因為規格或需求沒寫清楚,被開發人員講成需求異動。
- 結果
- 角色敵對:需求單位與開發單位不再是為了交付一個可以帶給使用者效益的產品,而是為了自己的目的,為了避免自己需要負額外的責任,而彼此攻訐。因此造成需求單位與開發單位根本不是一個團隊的情況。
- 責任推諉:團隊想的都是「我沒有錯,所以 delay 不是我的責任」,而不是把使用者需求放在最優先。
- 需求凍結:開發人員因為 deadline 的壓力,所以要求需求不能改,否則會 delay ,責任又要算在開發人員頭上。所以要嘛吵輸了,加班趕工出來諸多 bug 的產品;要嘛吵贏了,做出不符合使用者需求的產品;而這兩種都會降低使用者的滿意度。
- 品質低落:台灣的環境中往往 PM 的職級地位比開發人員高,因此最後為了滿足合約上的 deadline 或避免罰責等等,就會以「先求有,再求好」要求團隊,但最後往往是「先求有,沒時間求好」。技術債累積越來越多,結果就是現實世界的責任鏈模式,在鏈的最末端得扛最大的責任與成本。所以團隊就像 stack pop 一樣,開發人員受不了一個一個逃走,這也是為什麼專案公司工程師流動率往往很高的因素之一。
- 養 code 自重:為了效率最佳化,永遠都是用最熟悉的人的立場來估工時,所以永遠都是最熟悉該模組、流程的人來處理相關的需求。最終也只有那些人能維護自己的程式碼,那就像個潘朵拉的盒子,你永遠不知道打開之後會跑出哪一些牛鬼蛇神。因為黑箱,往往就會藏污納垢,但公司也沒輒,你還要求神拜佛希望他不會離開,否則那一些程式碼就沒人看得懂了。
Solutions
這邊所建議的解決方案,是在 Scrum 中很常用來估算需求複雜度的方式,但即使不是 Scrum 的團隊,建議讀者也可以依據其中的原則與設計目的,來找出最適合你們團隊的估算方式。請記住,沒有銀彈,別人的 best practice 不一定適用你的團隊,所以請先瞭解你團隊目前所碰到的問題為何,然後針對問題從別人的 practice 找出適合自己的解決方式,只要確保沒衍生出新問題,或是衍生的新問題其成本風險可被接受,那就是適合團隊的 solution 。
這邊用來估算需求複雜度的單位為 story point
(相對單位),而非工時(絕對單位)。這麼做有幾個原因:
- 比較不會因人而異:需求的複雜度往往不會因人而異,實作所需要的時間才會因人而異。
- 「相對」比「絕對」容易評估:若以工時來看,會比較需要估出絕對的數字,而且估算過程中會需要思考實作細節。用 story point 來估算複雜度,則只需要與其他需求進行相對比較大小即可。舉個例子,就像你很難明確指出「台北101有幾公尺高」,但你比較容易指出「台北101大概比高雄85大樓高出約 1.5 倍」。
- 估算 story point 壓力比估算工時小:關注在需求本身,而不用顧慮自身的資源與專案的資源,單純評估需求的複雜度。估算過程中,團隊成員壓力較小,就像遊戲般地進行軟體開發的其中一個環節。
雖然需求複雜度往往與工時正相關,但因為實作情況不同,實務上還是有可能出現 story point 高的 feature,工時比 story point 低的需求來得少。但在 Scrum 中,可以透過 iteration 的 sprint 來評估,每一次 sprint 團隊可消化的需求複雜度大概有多少。
接著針對解決方案的各個面向,進行說明。
When
在還沒有決定需求由誰來做之前,進行評估:這樣做的好處是,把開發人員的個人因素降到最低。因為不知道由誰來做,所以也無須所謂的 buffer 、灌水,或是因考量自身身上的任務或 deadline 而導致估算失真。
Who
只有要做事的人一起進行評估。兩個重點,第一:只有做事的人可以估。需求單位所估算的工時或複雜度是不客觀的,因為他們不是實際做事的人,沒有權力左右開發團隊依據需求評估的數字。如此也比較能避免發生由 deadline 來左右需求複雜度的評估。第二:做事的人一起估。因為不知道由誰來做,每個人一起估出來的數字,經過討論與重新估算後,才容易取得共識。每個人都有參與,會比較有參與感,也因為每個人都有參與,估算結果是大家一起決定出來的,所以未來由誰來做,都比較不會有所怨言。
What
使用 Planning Poker(費氏數列卡片)來估算 story point。
費氏數列有一個有趣的特性,每一個數字都是前兩個數字相加。另一方面來說,越大的數字與下一個數字的差距會更大。如上圖,8 與 13 的差距為 5 ,而 13 與 20 的差距為 7 。這跟估算需求複雜度有什麼關連呢?我們不是在上數學課啊。
估算也有個特性,就是越大的越估不準,把較大的需求或任務切到粒度較細時,往往估算起來就會比較精準。就像一個杯子中如果裝的都是大塊不規則的石頭,那麼中間的縫隙會比較多,這就是失準或浪費的部分。如果裝的是粒度較細,一樣不規則的石頭,縫隙相對會少一些,而且容易進行調整,能比較方便地填滿縫隙。
即使是前面的數字差距比較小,也沒有關係,因為本身數字小,代表挪動彈性大,風險低,如果因為某些因素時間估算失準需要調整,前面小數字的任務,大概就是加班 20 分鐘,而不是加班 2 天或 5 天的情況。
因為大的數字差距較大(費氏數列兩個前後值的差異比率趨近於 1.618),所以能避免估算時發生「到底這個複雜度是 20 還是 21 」的情況。要嘛 13 ,要嘛 20 ,要嘛 40 。這樣的級距差距可以突顯出大家對同一個需求估算的差異,因為幾乎都差了 1.5 倍以上,這比例對人類在判斷相對大小是相當容易的,也因此可以減少許多細微差異所引起不必要的重新估算流程成本。
另外,上面的圖片可以看到有幾個特殊的數字,分別為 0、無限大、問號。0 可能代表這個需求根本不需要作,或是已經完成了。無限大,則代表需求明確,但超過最大的那一張數字卡,代表這個需求需要再被細分成多個粒度較細的需求。問號,則代表需求有不明確的地方,需要 PO/PM 再說明或釐清清楚。
How
- 先定義出複雜度 1 的單位為何,例如一個單表綜合查詢的功能。因為我們的估算過程,是採相對比較大小,先定義出比較基準的單位,後面團隊估算時才有個比較的依據。
- 由主持人大聲唸出需求說明(例如 User Story Card),確定大家都瞭解需求後,每個人一起呈現自己所預估的複雜度。建議用 planning poker 的原因,是因為可以同一時間呈現大家評估的數字,而不是輪流說出自己評估的數字,輪流說出數字容易造成後面的人估算的結果,被前面的數字影響而失真。
- 若團隊中存在不同的預估數字,則由估最小與最大的兩人說明,自己評估為什麼覺得複雜或單純的原因。以上面的例子來說,在估算的過程,倘若出現有一人估算 story point 為 13 ,大部分人估算為 20 ,有另一人估算為 40 。13 與 40 幾乎差了 3 倍,那麼基本上一定存在某些重要資訊沒有被同步到。例如估算 13 的人覺得這個需求與過去某個需求幾乎相同,而這個需求並沒有想像中的複雜。而估算 40 的人可能因為對這個需求或流程不夠熟悉,所以覺得應該相對複雜。
- 最小與最大數字評估原因說明完畢後,再進行一次投票。如果投票結果仍存在不同的數字,且絕大部分的人有共識,沒共識的預估複雜度與有共識的複雜度只差一個級距,則可以詢問估算不同數字的成員,是否可以接受大家所評估的數字。
- 如果數字仍有差距一個級距以上,或是無法獲得共識,則重複步驟3~5,直到取得共識為止。
因為在估算過程可以幫助團隊中每個人來同步知識點,把每個人之間的技術、領域知識、經驗的互補綜效拉到最高。也可以將需求與作法釐清更清楚,減少重工或重新發明輪子的浪費。更甚至在實際開發時也可以從過程中瞭解,找誰來進行 pair programming 可以產生的綜效最高。也可以避免開發過程中出現馬後砲、責任推諉、只有某人熟某個領域的程式碼的問題。
再次強調,只有實際會執行任務或完成需求的人可以參與投票的過程,PO/PM 不能干涉。
這裡有個 15 分鐘左右的影片,用來說明在 Scrum 的 Refinement meeting 中,各角色該如何估算 story point,我覺得解釋地很清楚很好懂,提供給大家參考一下:Backlog Refinement Meeting
Why
透過這樣子的估算方式,會有幾個優點:
- 由做事的人共同決定出一個合理客觀的預估結果,有參與感且無怨言。
- 決定的結果是 PO 與 team 的共識,減少未來針鋒相對、各說各話的情況發生。
- 每個人都可以瞭解需求,未來每個人都可以擔任實作這個需求的人選,當需要支援時,也隨時可以有人一同開發或備援。
- 在還沒動手作之前,就可以釐清需求不明確或有疑慮的部分。
- 在還沒動手作之前,就可以在團隊中找到大家認同最好最有效率的作法。
- 除非整個 team 都是灌水的人,否則這個數字就反映了團隊共同認知的事實,PO 可從中了解需求與評估實作中間的落差。
- 透過比較需求之間複雜度的相對大小,未來 PO 對評估 iteration 可能可以承諾完成多少需求,也會有個比較的基底。
結論
透過上述的估算過程,這樣的決定公開、透明、客觀且有共識。對兩個角色而言:
- For PO/PM
- 不用擔心被某些特定的 member 呼嚨或灌水。
- 評估過程中瞭解需求或任務在實作時,潛藏的難度在哪。
- 瞭解需求是否還有需要說清楚或被誤解的部分。
- For Team
- 不再是不做事的人依照 deadline 給予一個不合理的時程限制。
- 在還沒開始動手進行任務之前,屬於開發人員之間的知識交換。不論因此增加或減少估算的數字,都讓需求更明確,預估更客觀。
- 因為還不知道由誰認領此任務,所以客觀且有共識,透過過程也可以知道誰對此任務熟悉度比較高,實際進行時,可以結對編程或知道找誰詢問與協助。
本文建議的解決方案,是一種 common solution ,重意不重形。重點不在於形式,而在於中間每個環節的設計目的,是為了解決什麼樣的問題。而這些問題,不一定存在於每個團隊。
因此建議讀者,如果你們團隊也有估算需求複雜度或工時的問題,可按照那樣的方向,把它改變成適合你們團隊的進行方式(例如你們一開始仍習慣工時,而不是 story point )。
blog 與課程更新內容,請前往新站位置:http://tdd.best/