2011年5月5日 星期四

Joel on Software - 無痛軟體時程

無痛軟體時程


作者: 周思博 (Joel Spolsky)
譯: Paul May 梅普華
編輯: Jeff Wang 王家麒
2000-03-29

去年十月, 美國東北部充斥著一個名為Acela產品的廣告. 這是一列由波士頓開到華盛頓的新開快速火車. 到處都是電視廣告,大看板和海報. 你會認為這麼多廣告一定創造出一些對Amtrak新快運服務的需求

可能會吧. 不過Amtrak根本沒有機會知道. Acela一延再延, 結果整個行銷活動在Acela服務推出前就結束了. 這讓我想起某位產品在推出前一個月被媒體大加讚揚的行銷經理, 他對我說:"真是大出風頭!只可惜你還不到這玩意!"

那些睪丸素過剩的自大狂遊戲公司總喜歡在自家網站上誇稱, 下個遊戲等"好了"自然就會推出. 至於時程?我們才不要那討厭的東西!我們是超酷的遊戲程式師! 大部份公司可沒這種福份. 問問蓮花公司吧. 他們的Lotus 123 3.0版初推出時需要用80286電腦, 這在當時可不怎麼普遍. 結果就把產品延後16個月推出, 努力讓程式能在8086的640K記憶體限制下執行. 等他們完成時, 微軟在Excel的開發上已經領先了16個月了, 更諷刺的是那時候8086已經完全過時了!

在我寫這篇文章時,Netscape的5.0版web瀏覽器幾乎已經拖了兩年.部份原因是他們下了個自殺式的決定, 把所有程式丟掉重頭開始. 同樣的錯誤已經讓安信達(Ashton-Tate), 蓮花,和蘋果的MacOS成為軟體歷史中的灰燼. Netscape瀏覽器的佔有率在這段期間由80%左右掉到大約20%, 而且完全無法對競爭者有任何反應, 因為他們最重要的軟體產品已經被拆成1000片散落在地上, 什麼事都做不了.其他因素都不夠看, 光這一個爛決定就成為Netscape炸爛自己的核彈了.(Jamie Zawinski's 世界聞名之怒詳述了整件事).

所以說你一定得定時程.幾乎沒幾個程式員想做這件事. 以我的經驗來說, 絕大部份人都完全不訂時程, 直接做了才說. 至於那少數幾個有做的,多是因為老闆一定要,只好敷衍著做一做, 而且除了那些同時相信"軟體專案一定會延誤"及"幽浮"的上級管理階層外, 沒人真的相信排出來的時程.

那麼為什麼沒人要訂時程呢?主要原因有二. 首先是執行起來很痛苦.其次是沒人認為值得做.明明知道排出來不準確, 為什麼要費事去做呢?大家都為時程一定是錯的, 而且時間過得愈久錯得愈離譜, 所以何必白費工夫呢?

下面提供一個簡單無痛的方法, 可以訂出確實無誤的時程.

1)使用微軟Excel. 不要用像微軟Project這種專門的程式. 微軟Project的問題在於它假設你要花大量時間處理相關連性(dependency). 所謂相關連性是指有兩件工作, 第一件工作必須在第二件工作開始前完成. 我發現就軟體而言, 相關連性實在是很明顯, 完全不需要花工夫正式追蹤.

Project另一個問題是假設你需要能按一個小按鈕就"重新均衡調整(rebalance)"時程.這表示程式會重新安排把工作指派給不同的人. 這就軟體來說完全行不通. 程式員是不能互換的.Rita的程式錯誤交由John來修正的話得花上好幾倍的時間才行. 另外如果你把負責使用者介面的程式員拉去處理WinSock問題, 她會卡在那裡花整個星期熟悉WinSock程式設計. 重點是Project是設計給建築辦公大樓用的, 不是寫軟體用的.

2)簡單就好. 我用的時程表標準格式簡單到你一定背得起來. 一開始只要七個欄位就好了:

[Image]

如果開發人員不只一個, 你可以讓每個人有自己一個表, 也可以加個欄位標出負責各項工作的人員.

3)每個功能應該包含多項工作. 所謂功能就像是在程式中增加拼字檢查. 增加拼字檢查包含好幾項程式員必須做的工作. 排時程最重要的部份就是排出這個工作表. 接下來是個基本原則:

4)只有實際要寫該程式的程式員才能排出該項的時程. 任何由管理階層排好時程交由程式人員執行的系統一定都會失敗. 只有實際執行工作的程式員才能找出完成功能所需的步驟. 也只有這個程式員才能估計每個步驟所需的時間.

5)把工作分得很細. 要讓時程真正產生作用, 這可是最重要的一環.分好的工作應該是以小時計而不是以天計. (當我看到以天甚至以週為單位的時程, 我知道這根本是玩假的). 你可能會認為把工作細分的時程只不過是精確一點而已. 錯!錯得離譜!當你訂時程時先由大項工作開始,然後再細分出細項工作, 就會發現結果完全不一樣, 而不光是精確一點而已. 這樣的時程出來的是完全不一樣的數字. 為什麼會這樣呢?

當你必須訂出細項工作時, 就得強迫自己實際地找出確實要進行的步驟. 要編寫foo這個副程式. 要建立某些對話框. 要讀取某某檔案. 這些步驟都很容易估計, 因為你以前寫過副程式建過對話框, 也讀過某某檔案.

如果你隨便劃分出大項工作(實作出文法修正功能),表示你根本沒有真正思考過要做的事情. 而如果你並未真正思考過要做的事情, 根本就不可能知道需要多久才能完成.

依據經驗來看, 每項工作耗時應在2到16小時之間. 如果時程上有項工作需要40小時(一週), 表示細分得還不夠.

細分工作還有另一個理由,就是能逼你設計那些要命的功能.如果你排了3週去做"Internet整合"這樣的粗略功能, 你就完蛋了. 如果你必須找出要寫哪些副程式, 就會逼自己把該項功能弄清楚. 因為被迫提早進行這種程度的規劃, 所以就能消除軟體專案中大量不穩定的成份.

6)記錄最初和目前的估計. 當你把某件工作第一次排進時程時, 先估計所需時數並填入Orig[inal] Est[imate]以及Curr[ent] Est[imate]欄位中. 當計劃進行時,你會發現某件工作所需的時間比估計的更長(或更短),就可以依需要更新Curr Est欄位. 這是由錯誤學習並教育自己準確估算工時的最佳作法.大部份程式員並不知道如何估計工時. 這是不要緊的. 只要你持續學習並隨時更新時程, 時程就會確實作用.(你可能必須削減功能或延期,不過時程本身還是能運作無誤,它會一直提醒你該砍功能或是必須延期了). 我發現大部份程式員只要一年工夫就能排出很好的時程.

當某項工作完成時, Curr Est欄的值會和Elapsed欄一樣,而Remain欄會變成0.

7)每天更新耗時(elapsed)欄. 你不用真的看著馬錶寫程式. 只要在回家前或鑽到桌下休息前(如果你是那些瘋子之一的話), 假裝自己已經工作8小時(哈!)並列出所做的工作, 再把8小時分配好填入工作對應的耗時欄中.Excel會自動計算剩餘欄的內容.

同時還要依據現實狀況更新各工作的Curr Est欄.每天更新時程應該只需要約兩分鐘. 所以才會說這是無痛的時程排法 -- 快速又容易.

8)加上國定假日,休假等等項目. 如果整個時程耗時約一年, 每個程式員可能會休10到15天的假. 時程中應該加一項叫"休假"的功能, 用作國定假日或其他會消耗人們時間的事情.這樣就可以把剩餘時間加總起來除以40 (就是考慮一切之後的所需工作週數), 計算出出貨的日期.

9)把除錯時間排入時程! 除錯是最難估計的.回想一下你前一個專案.除錯所佔的時間很可能是把程式寫出來的一到兩倍. 所以時程中一定要加這一項, 而且這有可能是最大的一項.

實際的作法如下. 讓我們假設一位開發人員正在做某件工作. Orig Est是16小時, 不過到目前為止已經用了20小時, 而且恐怕還要再做10小時. 所以開發人員在Curr Est和耗時欄分別輸入30及20.

等到達里程碑(milestone)時, 這所有的"落後"加總起來可能會有相當數量. 理論上為了因應這些延誤, 我們必須削減功能才能準時上市. 幸運的是可以削減的第一項功能就是名為緩衝(buffer)的功能, 而這個項目一開始就排了很多工時.

原則上, 開發人員會在寫程式時除錯. 程式員在應該除錯時絕對不該寫新程式. 基於兩項原因, 隨時都應該讓錯誤數目儘可能的少:

1)在寫出程式的同一天除錯會比較容易. 如果一個月後當你忘記程式運作細節時再來除錯, 就會變得非常困難而且要花很長的時間.

2)修正錯誤就像科學活動.不可能估計何時能有發現並解決問題.如果隨時都只有一兩個主要的問題, 表示未來無法估計的項目不多, 所以很容易估算產品推出的時間.反過來說, 如果主要的問題有幾百幾千個, 根本就不可能預測什麼時候才能把問題全部修好.

如果開發人員總會在寫程式時就把問題修好, 為什麼還要加上除錯項目呢? 有道理, 不過即使在寫程式時儘量修好所有的問題, 在到達里程牌時, 測試人員(內部或外部)總還是會找到真正困難的錯誤, 難免要有許多除錯的動作.

10)把整合時間排入時程中. 如果你的程式員不只一位, 難免會有兩人不一致的事情需要協調. 他們會各自建立功能近似的對話框, 這當然需要協調. 必須有人細查所有功能表,鍵盤快速鍵,工具列工具等等, 並且整理及組織所有大家不得不加的新功能表項目. 另外只要有兩個人把程式登入就會出現編譯錯誤. 這也得有人修正, 而且應該列入時程.

11)在時程中加上緩衝時間. 事物總是容易用完.你可能要考慮兩種重要的緩衝. 第一種:預防工作耗時超過預期的緩衝. 第二種:針對未預期但必要的工作的緩衝(這通常是因為管理階層決定某功能超級重要,絕對不能等到下一版).

你可能會很驚訝地發現,休假,國定假日,除錯,整合還有緩衝時間加起來超過實際做事的時間.如果被嚇到表示你程式寫得還不夠久, 不是嗎? 你要忽略這些項目的話後果自行負責.

12)絕對不要讓經理叫程式員縮減估計時間. 很多菜鳥軟體經理認為能用精細"緊密(短得不怍實際)"的時程, "激勵"程式人員做得更快. 我認為這種激勵根本是腦袋壞掉. 當我進度落後時, 我會覺得內疚消沈毫不積極. 當我進度超前時, 會非常快樂而且充滿生產力. 時程可不是玩心理遊戲的地方.

如果你的經理要求你縮短估計時間, 這裡告訴你要怎麼做. 在時程表上加一個叫Rick的估計(當然是假設你叫Rick)的新欄位. 把你的估計填進去.隨便經理怎樣要求,直接把她定的時間填入Curr Est欄位後就不要管了. 等專案經束時再看看誰的估計比較接近實際狀況. 我發現光是威脅說要這樣做, 效果就很驚人了, 特別是當你的經理瞭解到, 他們剛參加了一個看你能做得多的競賽時更是有效!

為什麼不適任的經理們總會試圖要程式員縮短估計時間呢?

當專案開始時技術經理會去見經營人員, 然後會得出一個他們認為三個月(實際上要9個月)做得到的功能列表. 如果你認為寫程式不需要先想清楚所需步驟, 然後估算出來某工作需時n, 實際上很可能會耗時超過3n. 在訂定真正的時程時, 把所有工作加總起來, 就會瞭解專案耗時遠比想像中多得多. 歡迎光臨真實世界.

不適任的經理的處理方法是想辦法讓員工做得更快. 這一點其實不太實際. 你或許能僱用更多員工, 不過他們需要時間適應, 可能前幾個月都只有一半的效率(還會拖慢必須引導他們的其他人員工). 而且無論如何, 在這個業界得要6個月才找得到好的程式員.

你可能可以讓員工在一年內全力以赴, 暫時提高10%的初版程式(譯註:指未整理除錯的程式)產量.算不上是什麼大躍進, 而且這樣有點太短視了.

你可能可以懇求員工不計辛勞超努力地工作,提高20%的初版程式產量. 砰!可惜除錯時間倍增了. 真是了不起的自爆蠢方法.

不過你絕對絕對不可能由n變成3n, 如果你自認有這種本事, 請寫信告知貴公司的股票代碼好讓我放空.

13)時程就像積木. 如果你有一堆積木, 積木太多塞不進箱子裡. 這時候你只有兩個選擇: 找個大點的箱子或拿掉一些積木. 如果你認為能在6個月內完成出貨, 可是時程上排的卻是12個月, 同樣的也只能延後出貨時間或是刪掉部份功能. 積木是不能壓縮的, 如果你自認為可以, 那只不過是在騙自己, 徒然讓自己失去一個真正能展望未來的好機會.

另外要知道, 如此維護時程還有其他好處, 就是能逼你自己刪除功能. 為什麼說這是好處呢? 假設你有兩個功能: 其中一個非常有用而且能讓產品變得超棒(比如Netscape 2.0里的table), 另一個很容易而且程式員很想寫(如BLINK標籤), 不過卻啥用處也不具備市場價值.

如果你不訂出時程, 程式員會先做簡單/有趣的功能. 然後等時間用完時你完全沒得選擇, 只能延後時程來完成有用/重要的功能.

如果你在開始作業前就排出時程, 就會瞭解必須削減某些項目,自然會把容易/有趣的功能砍掉而做有用/重要的功能. 這樣子強迫自己削減某些功能, 就能完成更強更好的產品, 不但功能更好而且又更早推出.

我想起Excel 5的製作. 我們最初的功能列表非常龐大, 遠遠超出我們的時程. 我們都在想:天啊! 這些全都是超級重要的功能!沒有巨集編輯精靈我們怎麼活得下去呢?

結果是我們沒得選擇, 所以只好配合時程把功能刪到不能再刪.每個人對於削減功能都很不爽. 為了安撫自己的感覺, 我們只好告訴自已說這不是在刪除功能, 只不過因為這些功能沒那麼重要, 所以延後到Excel 6而已.

當Excel 5幾近完成時, 我和同事Eric Michelman開始寫Excel 6的規格. 我們坐下來審視由Excel 5刪除移過來的"Excel 6"功能列表, 當我們發現這些被刪除的功能爛極了時真的是被嚇到了. 裡面竟然沒有一項值得做. 我認為即使是接下來的三個版本, 也完全沒有必要製作這些功能. 配合時程削減功能是我們所做過最好的事. 如果我們沒有這樣做, Excel 5可能會耗雙倍時間而且包含 50%無用的垃圾功能.(我絕不懷疑這就是Netscape 5/Mozilla現在的狀況:他們沒有時程也沒有明確的功能列表, 沒有人願意削減功能, 所以永遠無法推出. 等他們能推出時, 裡面會有很多IRC用戶端等根本不該做的無用功能.

附錄: 你該知道的Excel二三事

用Excel管理軟體時程如此好用, 原因之一就是對大部份Excel程式員而言, Excel的唯一用途就是維護軟體時程表! (只有少數程式員會用沙盤推演(what-if scenario)規劃的方式做事的...這些程式員!

共用列表 利用檔案選單的共用列表命令可以讓大家同時開啟並編輯檔案. 由於整個團體應該會持續更新時程, 這個功能幫助很大.

自動篩選 這是個篩選時程的好方法, 舉例來說, 你可以只檢視所有指派給你的功能. 再加上自動排序功能, 就能依優先度順序檢視所有指派給你的功能, 這實際上就是你的工作清單. 夠酷吧!

樞紐分析表 這是個檢視摘要及多重彙總表格的好方法.舉例來說, 你可以做一張圖顯示各優先度下各個開發人員的剩餘時數. 樞紐分析表就實在是個大創新.你一定要學會怎麼用樞紐分析表, 因為它能讓Excel增強一百萬倍.

Excel分析工具箱中的WORKDAY函數 是個在無痛時程中計算日曆天數的好方法.

文件來源: Painless Software Schedules (英文) 

沒有留言:

張貼留言