在前一回中提到要用務實的態度看待專案的期限,訂出明顯不合理的期限,很有可能造成崩潰的效應,不但得不到「取法於上,僅得為中」的效果,反而容易適得其反。從這個主題延伸下來,很容易就會討論到另外一個更基本的問題——應該如何制定開發工作的期限?

我相信有很多人關心這個議題,因為事實上,決定程式設計工作、甚至是開發工作的時程,都不是一件簡單的事情。

用拆解工作、程式碼行數估算的方式衡量
有很長一段時間,其實是一直到現在,人們都相信,可以試著利用不斷分解工作的方式,來估算專案的時程。主要的精神,便是將專案中的工作,逐漸分解成不同的小工作,再將每一個小工作分解成規模更小的工作,直到不需要分解為止。到了不需要分解或不能分解的層級時,代表它的規模夠小,也就容易估算究竟需要多少時間。

所以,在專案管理時,常利用WBS(Work Breakdown Structure)來表示專案中的工作,一方面協助規畫者思考專案中的實際工作項目,另一方面透過足夠的分解,也容易估算小規模工作所需的時間。透過估算結構中底層工作所需要的時間,進而估算出它們所構成的上層工作所需的時間。

這類型的估算方式基本上,若是能夠顧及整合工作所需的項目,大抵上在概念上沒有大問題。只要你能較準確估算出最底層工作所需的時間,也考慮到整合各分項工作時所需的工作,那麼,理論上可以依據WBS來估算出整體所需的時間。

之所以要將工作拆解到足夠小,當然有一個很大的作用,是因為規模愈小,愈容易估算。需要寫下一百行程式碼的程式設計工作,和最終需要寫下一萬行的程式設計工作(當然在估算時,你很有可能還不知道它最終需要寫下多少行的程式碼,因為它的規模太大了),在估算時程上來說,前者理應比較容易估算。

所以當拆解到夠小時,你就可以試著用別的指標來對工作所需的時間做評估,像是最傳統的作法——用原始碼的程式碼行數(Line Of Code)。像是估算一個工作需要寫下一百行程式碼,而在過去的工作中,一百行程式碼需要花費一小時來撰寫,那麼,你就會明白這個工作需要一個小時來完成。

影響專案估算的其他因素
不過,這樣的評估方式,並未考慮到工作本身的複雜度問題。一個複雜的工作,有可能只需要撰寫很少的程式碼行數,卻有可能相當耗費撰寫時間,甚至測試時間;而一個簡單的工作,或許需要寫下很多的程式碼行數,但其實並不會花去太多時間。數十行的程式碼可能要寫一天,但一天也有可能寫一千行。

從某個面向來解讀,愈是需要腦力、愈是需要嘗試的設計工作、愈難估算時程;而愈是勞力取向(也愈簡單,花力氣不花腦力)的程式設計工作愈容易估算時程。因此,才會有所謂的功能點(function point)分析的方式,來評估系統規模,以及所需的成本。

不過,在很多情況下,即使你花了很大的力氣,對系統的規模做了詳細的分析,也不見得可以完成實現精算後的結果。

一方面這是因為估算難免有所誤差,尤其是複雜度愈高的,誤差的範圍愈大。例如,一個高效的視訊編解碼程式,其實並不那麼容易就可以評估出它所需的工作時間。估算的誤差,若是半個月和一個月的差別,一來一往就差了半個月的時間了。此外,也有一些風險可能會發生,因而影響到最後的結果。像是程式設計者生病、和女朋友分手心情不好,也都會影響到最後實現的結果。

檢查點的達成 vs.里程碑的達成

依據我的經驗,估算能比較準確的程度,大概是數量級的層級上,例如幾分鐘、幾小時、幾天、幾週等等。一個工作花掉了3小時和6小時,看起來有100%的誤差,但是對你的實質影響其實並不會太大。但是需要6小時的工作,你不太容易會估算成需要3天。所以,在一些實際的開發場合裡,與其利用複雜的估算方法,不如將焦點擺在是否能依據它的複雜度,盡量估算出時間上的數量級。

有個現象很有趣,有些人喜歡在專案中設定非常多的查核點,針對每一個細項的工作都進行查核。做查核是好事,因為它讓你明白專案實際的進展和規畫之間的落差,以便調整你的計畫。

但是,有些人面對查核點的態度,卻是把它看得非常的嚴重。只要一旦錯過任何一個查核點,就覺得發生了延遲,便施加壓力要求開發人員要趕上。我個人認為,倘若你用這種方式來看待查核點,那麼反而會衍生出一些問題。很小的查核點沒有趕上,不應該被看待得這麼嚴重,你應該關心的是,專案中所設定的大型里程碑是否達成。

之所以用時間較長的里程碑來看待,是有幾個目的。第一,是為了避免開發人員為了趕上小的時間查核點而做一些應急的事情。當趕上每個查核點都必視為是必要的情況下,即使實際上無法在時間內完成有一定品質的工作內容,開發人員也很有可能採取炒短線的方式,做出一些看起來像是O.K.,但骨子裡充滿問題的成果。這就是炒短線,因為查核工作時,不見得能具體查核到每個細節,因此,這種方式會過關。但這無疑是浪費時間在這些炒短線的事情上面,實際上還是欠下了許多「技術債」,這些債在日後還是必須償還的。

所以,我們有時候會看到,在專案初期看起來每個查核點都沒問題,但是一旦進到了中後期,問題逐漸一一浮現,因為欠下的債開始要還了,接著一發不可收拾,開始錯過一個查核點、兩個、三個、…… 然後就大爆炸了。當然也有開發者不會用瞞騙的方式來安然的度過查核點,他們會自主性地選擇加班。但是太早讓開發人員加班也不健康,同樣是欠債,這樣的情況,會讓你在專案後期,失去透過加班來得到額外生產力的能力。

第二個之所以用時間較長的里程碑來看待的目的是:預估失準的情況會被稀釋,因為有些工作你會預估的比實際短一點,有些會預估得比實際長一點,但只要是在夠長的時間區段內、有夠多的工作,它們彼此之間就會相互中和,最後得到一個平均的結果。

專案規畫是手段,認清軟體最重要的目的
無論如何,很精準的掌握時間在很多情況下,都不是軟體開發中最重要的事。軟體開發最重要目的,是在可以接受的時間內,交付使用者最想要、最需要的功能,滿足他們的需求,而且具有足夠好的品質。預估再怎麼精準,只要需求變更的情況頻繁、超乎你的想像,就足以打亂你原先的規畫;只要存在幾個致命的品質問題,也足夠讓實際的時程變成完全不同的另一個樣子。

與其那麼的關心在時間問題上,不如更關心能否做好需求的管理,以及開發的品質。

更重要的是,我們做軟體的目的不是只是為了準時,而是為了提供使用者真的能用的軟體。當然,很多時候時間因素很重要,例如要趕上一個重要的參展活動,一旦錯過這個活動,就會錯失銷售的重要時機。但是一個工作實際上需要那麼多時間,就是需要那麼多時間,緊盯著時間表、持續地施加壓力不見得有助於此事。

事實上,要達成這個目的,你需要其他的觀念來輔助。在下一回中,讓我們繼續探討。

專欄作者

熱門新聞

Advertisement