編寫優質無錯程式碼(1) (轉)

gugu99發表於2008-01-25
編寫優質無錯程式碼(1) (轉)[@more@]一. 引言
八月上旬,深圳舉辦了一個討論會,主題是"編寫優質無錯程式碼"。這個討論
會吸引了深圳各大公司,通訊公司的員,分析員參加,並在討
論會後紛紛表示,這種討論會很有實際價值,希望將這種形式的討論會繼續
下去,形成一個論壇,以提高大家的水平和有價值的資訊資料。

這個活動的發起是從上開始的。我偶然看到了這個討論會的論題,發生
了興趣。本來週末的我一般是很懶的,沒什麼事情是不會出門的。而當我看
到這論題後,就給舉辦者發信表示願意參加。於是,一個週六的下午,我就
坐在了討論會的現場。參加完這個討論後,我覺得有必要把其中的精華部分
寫下來,和網路上的廣大程式設計師共享,於是就有了這篇文章。

二.主題:
編寫優質無錯的程式碼---討論會主題。
相信每個程式設計師都有這種希望,誰都不願意自己寫出來的程式碼在release之
後出錯,需要不停的修改維護。但是,主持人提出了這樣一個問題:"編寫
優質無錯程式碼是否必要?" 為什麼呢?我稍微解釋一下。在專案的時間很
緊張的時候,是按期完成任務重要,還是程式碼的穩定性,優質無錯重要呢?
主持人提出的四個具體問題是:
1、編寫優質無錯的程式碼的代價是什麼?
2、程式碼的質量重要還是編寫重要?
3、在壓力的情況下,你會犧牲質量來提高效率麼?
4、編寫優質無錯的程式碼是否意味著效率的降低?
對於第一個問題,編寫優質無錯程式碼的代價當然是時間,不過隨著程式設計人
員的逐漸豐富,所需要的時間也逐漸減少。
對於第二個問題,程式碼的質量比編寫效率重要。當你花了1周時間寫出來的
程式碼需要你花一個月或者更長的時間去de, 去修改錯誤,這種效率的損
失是得不償失的。
對於第三個問題, 這需要看專案經理或者產品經理的態度和專業精神了。
如果在一個專業的專案經理或者產品經理的指揮下,當然是首先保證質量其
次提高效率。而對於某些專案經理或者產品經理來說,按時完成任務是最重
要的,他們往往不在乎在軟體釋出之後花比開發時間長得多的時間去修改程
序,維護錯誤。因為,對於他們來說,首先是要完成任務,好給上級領導交
差,至於後期維護,就是另外一個任務了,維護花的時間多,正說明了他這
個專案的複雜性和難度。而對於開發人員來講,所希望的則正好相反。開發
人員不喜歡花太多的時間在一個爛攤子上。所以,在討論會上,大家紛紛表
示,應該讓專案經理或者產品經理也來聽一聽這個討論會:-)。
對於第四個問題,當然優質無錯程式碼不是意味著效率的降低,而是正好相反
,對提高效率有很好的促進作用。一個版本釋出之後,如果因為錯誤太多,
開發人員不得不去花很多時間修改bug, 甚至要從系統的體系結構方面去做
大的改動,重新編寫部分程式碼,這種效率的降低才是更大,更不能承受的。
而且,花了太多的時間在老版本的維護上,必然影響到新版本的工程進度,
直接影響到整個產品線的質量和進度,嚴重的甚至會毀掉整個產品。

對於這一個主題,我的回答是,在時間允許的範圍之內,儘量提高程式碼的質
量,不追求慢工出細活,不追求程式碼的100%無錯,但是要保證99%以上的無
錯。這樣,在時間的壓力下,在質量要求的束縛下,就要求程式設計師有一個良
好的習慣,和穩健的程式設計風格,以保證程式碼的優質無錯。這就是第二個問題
:什麼是編寫優質無錯的
程式碼的核心思想?優質無錯是相對的,而不是絕對的。任何程式碼,都不可能
說是絕對無錯的,但是在絕大部分情況下,是穩定的,強健的,優質的,無
錯的。每次釋出的時候,都會對上次的釋出版本做若干修改,增強功能的同
時,也要修改若干bug。
那麼,核心思想就是:
怎樣才能自動地查出這個錯誤。
怎樣才能避免這個錯誤。

三.編寫優質無錯程式碼的經驗
在說了上面很多理論性的問題之後,來看一看具體問題。
先來看一看一個具體的題目:(我本人就是先在網上看了這個題目,才對這
個討論會發生興趣的)
題目1:
作為開發團隊的一員,你需要實現一些庫提供給其他人使用。假設你實
現的一個函式原型如下:

int DoSomeThing(char* pParam)
{
...
}

你們約定好引數pParam不能為NULL,但為了防止者錯誤傳遞NULL,你需
要在你的函式里做判斷處理。
請問你會選擇那種方式,並說明原因?

(a) if (!pParam)
return 0;

(b) if (!pParam)
return ERROR_PARAM;

(c) if (!pParam)
pParam = "";
...

(d) if (!pParam)
throw EXCEPTION_ERROR_PARAM;

(e) if (!pParam)
MessageBox(...);

(f) assert(!pParam);

(附加說明一點,基於目前開發人員技術分佈情況和參與討論會的人員的技
術分佈情況,這次所列舉的例子都是C/C++和方面的,不涉及到VB, PB,
等語言。不過對於這些程式設計師,討論也是有借鑑作用的。)
關於這個問題,大概是所有的程式設計師都會遇到的。所以,在網上和討論會上,
都發生了激烈的爭論和意見交換。我大概把主要的幾種觀點記錄了一下,列
舉在下面:

1、選擇f的理由
因為非NULL是約定,所以可以確定是呼叫者的問題,f可以明確地指出這一
點,防止錯誤擴散。
我的附加說明: 防止錯誤擴散的意思是,如果用其他方式,比如throw
exception的方式,這個異常不一定會在呼叫此函式的上一層被捕捉到,可
能會被繼續丟擲直到最上一層或者直到在某一層被catch到,這樣的話,錯誤
就會距離發生地點很遠,擴散開來。
這一觀點,代表了一大部分的程式設計師的觀點。

2、反對用f
不贊成assert, assert更重要的作用是程式體裡面的一個註釋, 在閱讀程式
的時候起作用不能依賴他來檢測錯誤, 很大程度上assert容易使使用者依賴
它本不應該依賴的東西。
這也代表了部分程式設計師的觀點,認為assert是不可依賴的,而應該依賴於錯
誤檢測,比如返回值或者異常。

3、另外一種觀點
f和d都可取。如果沒有系統開銷的考慮,d則更好些。可以一舉兩得。如果沒
人catch這個exception,其結果就跟f一樣,按bug處理,dump core留下一
stack trace。如果有人catch,那就按執行錯誤處理......
但是返回一特初值表示錯誤,只是將錯誤上交,掩耳盜鈴而已。最終總得有個
人assert,messagebox,throw exception,perror+exit,或別得什麼的。既然已
經是約定,就乾脆付起責任。

4、一種反對d的理由
不可用d, 這就像你用人,卻不相信人一樣,偏要try,catch防範他。其實那個錯
是自己造成的,如果看到異常就容易不檢討自己。

5、關於觀點3的支援意見

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-998420/,如需轉載,請註明出處,否則將追究法律責任。

相關文章