第四章
①代碼規範
每個人對於什麽是“好”的代碼規範未必認同,這時我們很有必要給出一個基準線—什麽是好的代碼規範和設計規範
計算機只關心編譯生成的機器碼,你的程序采用哪種縮進風格,變量名有無統一的規範等,與機器碼的執行無關。但是,做一個有商業價值的項目,或者在團隊裏工作,代碼規範相當重要。“代碼規範”可以分成兩個部分:
1. 代碼風格規範——主要是文字上的規定,看似表面文章,實際上非常重要
2. 代碼設計規範——牽涉到程序設計、模塊之間的關系、設計模式等方方面面的通用原則
② 代碼風格規範
代碼風格的原則是:簡明,易讀,無二義性
提示:這裏談的風格是一家之言,如遇爭執,關鍵是要本著“保持簡明,讓代碼更容易讀”的原則
2.1 縮進
是用Tab鍵好,還是2、4、8個空格?
結論:4個空格,在Visual Studio和其他的一些編輯工具中都可以定義Tab鍵擴展成為幾個空格鍵。不用Tab鍵的理由是,Tab鍵在不同的情況下會顯示不同的長度,嚴重幹擾閱讀體驗。4個空格的距離從可讀性來說,正好
2.2 行寬
行寬必須限制,但是以前有些文檔規定的80字符行寬太小了(以前的計算機/打字機顯示行寬為80字符),現在時代不同了,可以限定為100字符
2.3 括號
在復雜的條件表達式中,用括號清楚地表示邏輯優先級
2.4 斷行與空白的{ }行
1. 最精簡的格式A:
if (condition) DoSomething();
else DoSomethingElse();
優點:因為可以節省幾行
缺點:不同的語句(Statement)放在一行中,程序調試(Debug)起來非常不方便,如果要一步一步觀察condition中各個變量(condition可能是包含函數調用的復雜表達式)的變化情況,單步執行就很難了
2. 有斷行的格式B:
if (condition)
DoSomething();
else
DoSomethingElse();
缺點:由於沒有明確的“{”和“}”來判斷程序的結構,在有多層控制嵌套時,這樣的格式就不容易看清結構和對應關系
3. 改進的格式C
if (condition) {
DoSomething();
} else {
DoSomethingElse();
}
缺點:不夠清晰
4. 每個“{”和“}”都獨占一行,即格式D
if (condition)
{
DoSomething();
}
else
{
DoSomethingElse();
}
2.5 分行
不要把多條語句放在一行上
a =1; b =2; // bogus
if (fFoo) Bar(); // bogus
更嚴格地說,不要把多個變量定義在一行上
Foo foo1, foo2; // bogus
2.6 命名
用單個字母給有復雜語義的實體命名並不可取,也是經過了實踐檢驗的方法叫“匈牙利命名法”。例如:
fFileExist // 表明是一個bool值,表示文件是否存在;
szPath // 表明是一個以0結束的字符串,表示一個路徑
2.7 下劃線
下劃線用來分隔變量名字中的作用域標註和變量的語義,如:一個類型的成員變量通常用m來表示,或者簡單地用一個下劃線“”來做前綴。移山公司規定下劃線一般不用在其他方面
2.8 大小寫
由多個單詞組成的變量名,如果全部都是小寫,很不易讀,一個簡單的解決方案就是用大小寫區分它們。
- Pascal——所有單詞的第一個字母都大寫
- Camel——第一個單詞全部小寫,隨後單詞隨Pas-cal形式,這種方式也叫lowerCamel
一個通用的做法是:
- 所有的類型/類/函數名都用Pascal形式,所有的變量都用Camel形式
- 類/類型/變量:名詞或組合名詞,如Member、ProductInfo等
- 函數則用動詞或動賓組合詞來表示,如get/set、RenderPage()
2.9 註釋
需要註釋什麽?不要註釋程序是怎麽工作的(How),程序本身就應該能說明這一問題
//this loop starts the i from0 to len, in each step, it
// does SomeThing
for (i =0; i < len; i++)
{
DoSomeThing();
}
以上的註釋是多余的。註釋是為了解釋程序做什麽(What),為什麽這樣做(Why),以及要特別註意的地方,如下
/go thru the array, note the last element is at [len-1]
for (i =0; i < len; i++)
{
DoSomeThing();
}
復雜的註釋應該放在函數頭,很多函數頭的註釋都用來解釋參數的類型等,如果程序正文已經能夠說明參數的類型in/out,就不要重復!
註釋也要隨著程序的修改而不斷更新,一個誤導的(Misleading)註釋往往比沒有註釋更糟糕
另外,註釋(包括所有源代碼)應該只用ASCII字符,不要用中文或其他特殊字符,否則會極大地影響程序的可移植性。
在現代編程環境中,程序編輯器可以設置各種美觀得體的字體,我們可以使用不同的顯示風格來表示程序的不同部分。
註意:有些程序設計語言的教科書對於基本的語法有詳細的註釋,那是為了教學的目的,不宜在正式項目中也這麽做
3. 代碼設計要規範
4. 代碼復審
正確定義:看代碼是否在“代碼規範”的框架內正確地解決了問題
軟件工程中最基本的復審手段,就是同伴復審
1. 代碼復審的目的在於:
-
找出代碼的錯誤,比如:
-
編碼錯誤,比如一些碰巧騙過了編譯器的錯誤
-
不符合團隊代碼規範的地方
-
-
發現邏輯錯誤,程序可以編譯通過,但是代碼的邏輯是錯的
-
發現算法錯誤,比如使用的算法不夠優化,邊界條件沒有處理好等
-
發現潛在的錯誤和回歸性錯誤—當前的修改導致以前修復的缺陷又重新出現
-
發現可能需要改進的地方
-
教育(互相教育)開發人員,傳授經驗,讓更多的成員熟悉項目各部分的代碼,同時熟悉和應用領域相關的實際知識
結對編程
結對編程的優勢
-
在開發層次,結對編程能提供更好的設計質量和代碼質量,兩人合作解決問題的能力更強
-
對開發人員自身來說,結對工作能帶來更多的信心,高質量的產出能帶來更高的滿足感
-
在企業管理層次上,結對能更有效地交流,相互學習和傳遞經驗,分享知識,能更好地應對人員流動
總之,如果運用得當,結對編程可以取得更高的投入產出比(Return of Investment)
第四章