1. 程式人生 > >構建之法學習(4)

構建之法學習(4)

控制 重要 protect 運算 包裝 二義性 lin c++ 基類

本周學習的內容是兩人合作

計算機只關心編譯生成的機器碼,你的程序采用哪種縮進風格,變量名有無統一的規範等,與機器碼的執行無關。但是,做一個有商業價值的項目,或者在團隊裏工作,代碼規範相當重要。“代碼規範”可以分成兩個部分:
1. 代碼風格規範。主要是文字上的規定,看似表面文章,實際上非常重要。
2. 代碼設計規範。牽涉到程序設計、模塊之間的關系、設計模式等方方面面的通用原則。

代碼風格的原則是:簡明,易讀,無二義性。提示:這裏談的風格是一家之言,如遇爭執,關鍵是要本著“保持簡明,讓代碼更容易讀”的原則,看看爭執中的代碼規範能否讓程序員們更好地理解和維護程序。

復雜的註釋應該放在函數頭,很多函數頭的註釋都用來解釋參數的類型等,如果程序正文已經能夠說明參數的類型in/out,就不要重復!註釋也要隨著程序的修改而不斷更新,一個誤導的(Misleading)註釋往往比沒有註釋更糟糕。另外,註釋(包括所有源代碼)應該只用ASCII字符,不要用中文或其他特殊字符,否則會極大地影響程序的可移植性。在現代編程環境中,程序編輯器可以設置各種美觀得體的字體,我們可以使用不同的顯示風格來表示程序的不同部分。

代碼設計規範不光是程序書寫的格式問題,而且牽涉到程序設計、模塊之間的關系、設計模式等方方面面,這裏又有不少內容與具體程序設計語言息息相關(如C、C++、Java、C#),但是也有通用的原則,這裏主要討論通用的原則。如果你只想為了“爽”而寫程序,那麽可以忽略下面的原則;如果你寫的程序會被很多人使用,並且你得加班調試自己的程序,那最好還是遵守下面的規定。

註意,除了關於異常(Exception)的部分,大部分其他原則對C#也適用。
1. 類
1)使用類來封裝面向對象的概念和多態(Poly-morphism)。
2)避免傳遞類型實體的值,應該用指針傳遞。換句話說,對於簡單的數據類型,沒有必要用類來實現。
3)對於有顯式的構造和析構函數的類,不要建立全局的實體,因為你不知道它們在何時創建和消除。
4)僅在必要時,才使用“類”。
2. class vs. struct如果只是數據的封裝,用struct即可。
3. 公共/保護/私有成員(public、protected和private)按照這樣的次序來說明類中的成員:public、pro-tected、private。
4. 數據成員
1)數據類型的成員用m_name說明。
2)不要使用公共的數據成員,要用inline訪問函數,這樣可兼顧封裝和效率。
5. 虛函數(Virtual Function)
1)使用虛函數來實現多態(Polymorphism)。
2)僅在很有必要時,才使用虛函數。
3)如果一個類型要實現多態,在基類(Base Class)中的析構函數應該是虛函數。
6. 構造函數(Constructors)
1)不要在構造函數中做復雜的操作,簡單初始化所有數據成員即可。
2)構造函數不應該返回錯誤(事實上也無法返回)。把可能出錯的操作放到HrInit()或FInit()中。

7. 析構函數(Destructor)
1)把所有的清理工作都放在析構函數中。如果有些資源在析構函數之前就釋放了,記住要重置這些成員為0或NULL。
2)析構函數也不應該出錯。
8. new和delete
1)如果可能,實現自己的new/delete,這樣可以方便地加上自己的跟蹤和管理機制。自己的new/delete可以包裝系統提供的new/delete。
2)檢查new的返回值。new不一定都成功。
3)釋放指針時不用檢查NULL。
9. 運算符(Operators)
1)在理想狀態下,我們定義的類不需要自定義操作符。確有必要時,才會自定義操作符。
2)運算符不要做標準語義之外的任何動作。例如,“==”的判斷不能改變被比較實體的狀態。
3)運算符的實現必須非常有效率,如果有復雜的操作,應定義一個單獨的函數。
4)當你拿不定主意的時候,用成員函數,不要用運算符。
10. 異常(Exceptions)
1)異常是在“異乎尋常”的情況下出現的,它的設置和處理都要花費“異乎尋常”的開銷,所以不要用異常作為邏輯控制來處理程序的主要流程。
2)了解異常及處理異常的花銷,在C++語言中,這是不可忽視的開銷。
3)當使用異常時,要註意在什麽地方清理數據。
4)異常不能跨過DLL或進程的邊界來傳遞信息,所以異常不是萬能的。
11. 類型繼承(Class Inheritance)
1)僅在必要時,才使用類型繼承。
2)用const標註只讀的參數(參數指向的數據是只讀的,而不是參數本身)。
3)用const標註不改變數據的函數。

軟件工程中最基本的復審手段,就是同伴復審。
1. 誰來做代碼復審?即最有經驗、熟悉這一部分代碼的人。對於至關重要的代碼,我們要請不止一個人來做代碼復審。
1)代碼復審的目的在於:
2)找出代碼的錯誤,比如:
2. 編碼錯誤,比如一些碰巧騙過了編譯器的錯誤
3. 不符合團隊代碼規範的地方
4. 發現邏輯錯誤,程序可以編譯通過,但是代碼的邏輯是錯的
5. 發現算法錯誤,比如使用的算法不夠優化,邊界條件沒有處理好等
6. 發現潛在的錯誤和回歸性錯誤—當前的修改導致以前修復的缺陷又重新出現
7. 發現可能需要改進的地方
8. 教育(互相教育)開發人員,傳授經驗,讓更多的成員熟悉項目各部分的代碼,同時熟悉和應用領域相關的實際知識

構建之法學習(4)