2010-06-14 13:47:42Sam Blog

邁向高品質程式碼的12個步驟

如果你能把這12件事做好,就能建立一個能穩定交出產品的紀律團隊。

1. 你有使用原始碼控制系統嗎?
我使用過一些商用原始檔控制系統(source control packages),也用過免費的CVS,所以我可以告訴你CVS相當不錯!如果你沒有原始碼控制系統,一旦需要與程式設計人員合作就相當麻煩了。因為程 式設計人員無法知道其他人做了什麼,也無法輕易回復成出錯前的狀態。而且原始碼控制系統還有另一個優點,就是原始碼會被簽出(check out)到每位程式設計人員的硬碟裡。我還沒看過哪個用了原始碼控制的專案會遺失大量程式的。

2. 你能用一個步驟建出所有結果嗎?
我的意思是:從最新的原始碼快照開始,要花多少步驟才能建立出貨用的軟體?好的團隊會有單一個腳本檔,只要執行這個腳本,就會從頭簽出所有檔案、 編譯每一行程式、建立執行檔(包含所有不同版本、語言以及#ifdef組合)、製作安裝程式,並且產生最後要用的媒體格式:光碟片、網站下載或是其他各種 格式。

如果這個程序不是只有一個步驟,就會容易出錯。另外,當出貨時程緊迫時,修正「最後一個」問題、製作最終執行檔等過程必須要快速完成。如果程式編譯和安裝檔製作等動作需要20個步驟才能完成,你一定會急瘋了,然後做出一些蠢事。

就是為了這一點,我的前一家公司把原本使用的WISE換成InstallShield。因為我們必須透過NT工作排程器,在夜間用腳本自動製作出 安裝程式,由於WISE無法透過工作排程器半夜執行,因此就把它丟掉了(親切的WISE員工跟我保證,他們的最新版一定會支援夜間執行)。

3. 你有進行每日編譯嗎?
在使用原始碼控制工具時,有時程式設計人員會不慎提交(check in)某些內容而導致編譯失敗。舉例來說,某人新增了一個原始檔,整個程式在他的機器上都能正常編譯,可是卻忘記把新增的原始檔加到原始碼控制程式庫中。 結果這位仁兄非常健忘且愉快地鎖上機器回家了,導致其他人無法做事,也只好很不爽地回家。

導致編譯失敗是非常糟糕的事情(又經常發生),這時每日編譯就很有幫助了,它能保證不會有漏網之魚。在大型的團隊中,要確保能立即修正編譯失敗的 最佳方法就是每天下午(像是午餐時間)重新編譯。大家在午餐前盡可能的提交檔案,等大家用餐完畢編譯也已經完成。若結果顯示正常,很好!大家可以簽出最新 版的原始碼繼續工作;如果有問題就將它搞定,而其他人還可以用前一版沒問題的程式繼續幹活。

Excel團隊有個規定,導致編譯失敗的人必須從此負責重新編譯的動作當作處罰,直到有其他人出錯為止。這能讓大家盡量避免造成編譯失敗,同時也是個讓大家輪流熟悉重新編譯的好方法。在我的文章:「每日編譯是你的好朋友」裡有更多每日編譯的資料。

4. 你有沒有問題(bug)資料庫?
無論如何,只要你在寫程式時(只有一個人寫也是一樣),沒有一套良好的資料庫列出程式中所有的問題,就一定會產生出品質低劣的程式碼。很多程式設 計人員自認能把問題清單記在腦子裡,才怪!我從來沒辦法一次記住超過二或三個問題,而且會在第二天早上,或是趕著出貨時把它們全部忘掉。你一定要正式地記 錄問題。

問題資料庫可大可小。一個最簡單有用的問題資料庫必須包含每個問題的下列資料:

● 重現問題的完整步驟。

● 應該看到的行為。

● 實際看到的(有問題的)行為。

● 被指派的負責人。

● 是否已修正。

如果你是因為覺得問題追蹤軟體太複雜才不追蹤問題,請建立五欄的簡單表格,填入上述資料,然後開始使用吧!想要深入瞭解問題追蹤,請參閱「無痛錯誤追蹤」一文。

5. 你會先把問題都修好之後,才寫新的程式嗎?
古早第一版的Microsoft Word for Windows被視為「死亡行軍」型的專案。進度一直處在落後的情況。整個團隊的工作時間長得離譜,專案卻一延再延三延,大家都承受無比的壓力。拖了幾年 後,那個鬼東西終於上市了,微軟就把整個團隊送到Cancun(墨西哥著名海灘)渡假,然後再坐下來做深度反省。

他們發現產品經理過度堅持要維持「進度」,而程式設計人員只能匆匆經過編碼階段。而且正式的時程並未包含錯誤修正這個階段,於是寫出的程式碼非常 糟糕。此外,也沒有人試圖要減少問題數量,而事實剛好相反!有位程式設計人員要寫支程式以計算一行文字的高度,結果他只寫了「return 12;」,並等問題報告出爐指出這個函數功能不對。於是,時程表變成一份等著被轉換成問題的功能列表,事後檢討時則稱之為「無窮錯誤法(Infinite defects methodology)」。

為了修正這個問題,微軟全面採用所謂的「零錯誤作法(Zero defects methodology)」。公司裡很多程式設計人員聽了都不禁竊笑,因為感覺就像是管理階層認為能用行政命令降低錯誤數量一樣。實際上,「零錯誤」是指 無論何時都要先修正錯誤才能寫新程式。原因如下:

一般來說,愈晚修正錯誤,修正時所付出的成本(時間及金錢)愈高。舉例來說,當你打錯字或出現編譯器會發現的語法錯誤,就修正只是小事一樁。

若你的程式第一次執行出錯時,應該也能立即改正,因為整個程式還在你腦海裡。如果要為幾天前寫的程式除錯,應該需要回想一陣子吧!不過,當你重讀所寫的程式後,就會記起所有細節,並在適當時間內把問題修好。

若是要為幾個月前寫的程式除錯,那很有可能已經忘掉一大半,要修正簡直難上加難!或許,你正在替別人的程式除錯,而當事人遠在阿盧巴渡假,這時除 錯的任務就像科學一樣:你得條理分明、小心翼翼地慢慢來,也無法確定要多久時間才能解決。另外,如果要為已出貨的程式除錯,修正問題的代價就更難以估算 了!

這就是要立即修正問題的理由之一,因為這樣做能少花點時間。另一個理由是,寫新程式的時間遠比修正現有錯誤的時間容易估計。舉例來說,如果要你估 計寫串列排序的程式需時多久,你應該能估算得相當準確;但假如你的程式在裝了Internet Explorer 5.5之後有問題,要估計需要多久才能修好,恐怕用猜的都猜不出來,因為你不知道(當然不知道)問題點在哪裡。要找出問題可能就要花上三天,但也可能兩分 鐘內解決。

如果時程裡包含很多有待修正的問題,那麼這種時程是不可靠的。假如把已知的錯誤都修好了,剩下的就只有新程式了,那麼時程就會變得非常準確。

把錯誤數量維持在零還有另外一項優點,就是面對競爭時反應可以更快。有些程式設計人員認為這樣做可讓產品隨時推出。一旦競爭者推出某個殺手級新功能來搶客戶時,只要把該功能加上去,即可立即出貨,不必修正累積下來的大量問題。