代碼大全讀書筆記

最近拜讀了《代碼大全》,這部大塊頭確實經典,涉及到了軟件開發的方方面面。有點後悔沒有早些閱讀,值得推薦給還沒讀過的朋友。它並非針對某種語言的武林祕籍,應該能夠看做是基礎內功修煉吧。程序員

筆記比較簡略,只供簡單查閱~編程

1、開發前期準備相關

1.需求階段:安全

  • 發現錯誤的時間要儘可能接近進入該錯誤的時間。因爲需求是首先進行的活動,因此需求階段引入的缺陷可能在系統中潛伏的時間最長,代價也更昂貴。
  • 若是沒有一個良好的問題定義,你努力解決的多是一個錯誤的問題。
  • 明確的需求有助於確保用戶駕馭系統的能力;
  • 明確的需求有助於避免爭論。
  • 重視需求有助於減小開始編程開發以後的系統變動狀況。
  • 一個形象的比喻:需求像水。若是凍結了,就容易在上面開展建設。
  • 開發過程可以幫助客戶更好的理解本身的需求,這每每是需求變動的主要來源。

2.架構架構

  • 架構應詳細定義所需的主要的類。瞄準80/20準則:對構成系統的80%功能的20%的類進行詳細說明。
  • 架構應創建一套有關錯誤消息的約定。
  • 架構的整體質量:
  • 《人月神話》的中心論題,說的就是大型系統的本質問題是維持其「概念完整性」。
  • 好的架構設計應該與待解決的問題和諧一致。
  • 架構應該描述全部主要決策的動機。
  • 優秀的軟件架構很大程度上是與編程語言無關的。

3.構建決策框架

  • 深刻一種語言去編程
  • 肯定你在技術浪潮中的位置,並相應調整計劃和預期目標。

2、編寫高質量代碼

1.類編程語言

軟件的首要技術使命就是管理複雜度。能夠經過把整個複雜系統分解爲多個子系統下降問題的複雜度。函數

關於封裝:類很像是冰山,八分之七都在水面如下,你只能看到水面以上的八分之一。工具

抽象數據類型(ADT)是指一些數據以及在這些數據上所能進行的操做的集合。佈局

考慮類的一種方式,就是把它看做抽象數據類型,再加上繼承和多態兩個概念。性能

警戒有超過7個數據成員的類。

儘可能使用多態,避免的大量的類型檢查。

構造函數:

  • 若是可能,應該在全部的構造函數中初始化全部的數據成員。
  • 用私有構造函數實現單件屬性。

2.子程序

  • 子程序是爲實現特定的目的而編寫的一個可被調用的方法或過程。函數是有返回值的子程序;過程是沒有返回值的子程序。
  • 合理的參數個數,上線大概在7個左右。

3.防護式編程

  • 主要思想:子程序不該傳入錯誤數據而被破壞,哪怕是其餘子程序產生的錯誤數據。
  • 在代碼中保留多少防護式代碼?
  • 保留那些檢查重要錯誤的代碼;
  • 去掉檢查細微錯誤的代碼;
  • 爲技術支持人員記錄錯誤信息;
  • 確保留在代碼中的錯誤信息是友好的。

4.僞代碼建立子過程

  • 用相似英語的語句描述特定的具體操做;
  • 避免使用目標編程語言中的語法元素;
  • 在乎圖的層面編寫僞代碼;
  • 在一個足夠低的層次上編寫僞代碼,以便於近乎自動地從他生成代碼,而後把它編程代碼中的註釋。

Image


3、變量

1.使用變量的通常事項

Image(1)

2.變量命名

  • 爲變量命名時要考慮的重要事項是,該名字要徹底、準確地描述出該變量所表明的事物。
  • 較長的名字適用於較少使用的變量或者全局變量;較短的名字適用於局部變量或者循環變量。
  • 代碼閱讀的次數要遠遠大於編寫的次數。要確保你所取的名字更側重於閱讀方便而不是編寫方便。

3.特定數據類型命名

①.限定詞命名

  • 若是變量名中含有Total,Average,Sum,Max等限定詞,請記住把限定詞加在變量名的最後
  • 用Count和Index代替Num

關於Num限定詞容易產生歧義,例如:numStudents表示學生數,studentNum表示學生序號。爲了不這種歧義,能夠用Count和Index來代替,好比用studentCount表示學生總數,而用studentIndex表示學生序號。

②.爲循環索引命名

  • 若是一個變量要在循環以外使用,那麼就要使用一個i,j,k以外更有意義的名字。
  • 若是循環不是隻有幾行,那麼讀者很容易忘記i原本的含義,所以最好給循環下標取一個比i更有意義的名字。

③.爲狀態變量命名

爲狀態變量取一個比flag更好的名字。標記通常使用枚舉類型、具名常量或者用做具名常量的全局變量來對其賦值。

④.爲布爾變量命名

  • 謹記典型的布爾變量名:found,error,success,ok。
  • 給布爾變量賦予隱含「真/假」含義的名字,並且能夠省略變量名開頭的Is前綴
  • 使用確定的變量名

⑤.爲具名常量命名

應該根據該常量所表示的含義,而不是該常量所具備的數值來命名。


4、表驅動法

  • 表驅動法是一種編程模式,從表裏面查找信息而不使用邏輯語句(if和case)。
  • 表提供了一種複雜邏輯和繼承結構的替代方案。

5、通常控制方法

1.布爾表達式

  • 拆分複雜的判斷而引入新的變量;
  • 把複雜的表達式作成布爾函數;
  • 用決策表代替複雜的條件。

2.按照數軸的順序編寫數值表達式;

3.將複雜度下降到最低是編寫高質量代碼的關鍵。


6、代碼改善

1.軟件質量的廣泛原理就是改善質量以下降開發成本。

2.提升生產效率和改善質量的最佳途徑就是減小花在代碼返工上的時間,不管返工是由需求、設計改變仍是調試引發的。

3.結對編程,經過複查能夠快速地將全部開發者的水平提升到最高優秀的開發者的高度。


七.開發者測試

1.白盒測試指的是測試者清楚對象內部工做機制的測試,測試本身開發的程序應該使用這種測試方式。

2 測試的特性:

  • 測試的目標與其餘測試活動背道而馳,測試的目的是找出錯誤。
  • 測試永遠不可能證實程序中完全沒有錯誤。
  • 測試的結果是軟件質量的一個指示器,可是測試自己並不能改善軟件質量,這種妄想就像每天經過稱體重來減肥同樣。假如但願改進你的軟件質量,僅用更多的測試是沒用的,你須要的是更高質量的開發。

3 推薦開發者的測試方式

  • 對每一項相關的需求進行測試,以確保需求都已經被實現;
  • 基礎測試和數據流測試;
  • 使用一個檢查表,記錄你在本項目中迄今爲止所犯的,以及在過去的項目中中所犯的錯誤類型,這有助於「猜想錯誤」的準確性;
  • 推薦測試先行。

4 測試技巧錦囊

  • 結構化的基礎測試
  • 須要去測試程序中的每行代碼至少一次。
  • 所需基礎測試最少用例數量的計算方式:

對經過子程序的直路,開始記爲1;

遇到如下關鍵字時,加1,好比:if,and,or,while,repeat,for;

遇到每一個case語句,加1,若是case語句沒有默認語句,再加1.

5.測試數據生成器

  • 爲了系統的對程序的某些部分進行測試,你可能會寫一些代碼。
  • 正確設計的測試數據生成器能產生意想不到的、不尋常的測試用例;
  • 比起手工構造測試數據,數據生成器可以更加完全地對程序進行測試。

8、調試

①關於調試

  • 理解你正在編寫的程序;
  • 明確你犯了那種類型的錯誤;
  • 從代碼閱讀者的角度分析代碼質量;
  • 審視本身解決問題的方法,花點時間來分析並改善你的調試方法,可能就是減小程序開發時間的最好方法
  • 審視本身修改正缺陷的方法。

②尋找缺陷步驟

  • 把錯誤狀態穩定下來,也就是能讓缺陷穩定的重現,這幾乎是最有挑戰的工做之一;
  • 肯定錯誤的來源;
  • 修補缺陷;
  • 對修補的缺陷進行測試;
  • 查找是否還有相似的錯誤。

③修復缺陷

  • 在動手以前先要理解問題,知道你能真正理解問題,每次都能正確地預測結果爲止;
  • 理解程序自己,而不只僅是問題
  • 驗證對錯誤的分析;
  • 放鬆一下;
  • 保存最初的源代碼,至少你能對新舊代碼進行比較,看到底改了哪些地方;
  • 治本,而不是治標;
  • 修改代碼時必定要有恰當的理由;
  • 一次只作一個改動;
  • 檢查本身的改動;
  • 增長暴露問題的單元測試;
  • 搜索相似的缺陷,若是你想不出如何查找相似缺陷,這就意味着你尚未徹底理解問題。

④調試工具

  • 源代碼比較工具;
  • 編譯器的警告信息,把編譯器的警告級別設置爲最嚴格;
  • 加強的語法檢查和邏輯檢查;
  • 執行性能剖測器;
  • 測試框架;
  • 調試器;

9、重構

1.軟件演化類型

  • 在修改中軟件的質量要麼提升,要麼惡化。
  • 軟件演化的基本原則就是,演化應當提升程序的內在質量。

2.重構的理由

  • 代碼重複:DRY,Do not Repeat Yourself;
  • 冗長的子程序:不多會用到長度超過一個屏幕的子程序。改善方法是提升其模塊性-增長定義完善、命名準確的子程序,讓他們各自集中力量作好一件事;
  • 循環過長或嵌套過深;
  • 內聚性太差的類;
  • 擁有太多參數的參數列表;
  • 變化致使多個類的相同修改;
  • 同時使用的相關數據並未以類的形式組織;
  • 過多使用基本數據類型;
  • 某個類無所事事;
  • 中間人對象無事可作;
  • 子程序明明不恰當。只要看到某個子程序命名有問題,就應該當即着手修改。
  • 註釋被用於解釋難懂的代碼。不要爲拙劣的代碼編寫文檔——應當重寫代碼;
  • 程序中的一些代碼彷佛是在未來的某個時候纔會用到。對將來需求有所準備的代碼並非編寫大量空中樓閣式的代碼,而是儘量將知足當前需求的代碼清晰明白的表現出來,使將來的程序員理解這些代碼到底完成了什麼功能,沒完成什麼功能,以便根據他們的需求進行調整。

3. 數據級的重構

  • 用具名常量代替神祕數值;
  • 使變量的名字更加清晰且傳遞更多信息;
  • 用函數代替表達式;
  • 將基礎類型轉化爲類。若是一個基礎類型須要額外的功能或者額外的數據,那麼就應該把基礎類型轉化爲類,並添加你所須要的行爲;
  • 將一組類型碼轉換爲類或者枚舉類型;

4.語句級的重構

  • 分解布爾表達式
  • 將複雜布爾表達式轉換爲命名準確的布爾函數;
  • 在嵌套的if-then-else語句中應該一知道答案就返回,而不是賦值給一個返回值

5.子程序級重構

  • 提取子程序或者方法
  • 將冗長的子程序轉換爲類
  • 合併類似的子程序,經過參數區分他們的功能

6 類接口的重構

  • 將成員函數放到另外一個類中
  • 將一個類變爲兩個類。若是一個類中的成員函數完成兩種大相徑庭的功能,將這樣的類轉換爲兩個類
  • 對於不能修改的類成員去掉其set函數。若是一個成員在對象被建立時設置,以後遍再也不容許修改,那麼刪除其set函數,而是在構造函數中進行初始化。

7 系統級重構

  • 使用工廠函數而不是簡單的構造函數;
  • 用異常代替錯誤代碼,或者反其道而行之,取決於你的錯誤處理策略,請確保代碼使用了標準的錯誤處理方法。

8. 安全的重構

  • 保存初始代碼。要保證你還能回到代碼的初始狀態。
  • 重構的步伐請小些。這樣才能理解所作修改對程序的所有影響。
  • 同一時間只作一項重構。在進入到下一項重構以前,對代碼進行從新編譯和測試。
  • 把要作的事情一步步列出來。寫出一份重構列表可以讓你在修改時保持思路連貫。
  • 設置一個停車場。把你須要在將來進行而如今能夠暫且放在一遍的修改工做記錄下來。
  • 利用編譯器警告信息。把編譯器的警告級別設置爲最嚴格。
  • 從新測試。應該把從新測試做爲修改代碼工做的補充。
  • 檢查對代碼的修改。若是說第一次運行程序時檢查代碼是必要的,那麼接下來修改代碼的過程當中,時刻檢查代碼則更爲必要。另外,應該把簡單的修改看成複雜的修改對待。
  • 根據風險級別來調整重構方法。尤爲是對於有必定風險的重構,謹慎才能避免出錯。

9.重構策略

  • 在增長子程序的時候重構
  • 在添加類的時候重構
  • 在修補缺陷的時候重構
  • 關注於易出錯的模塊
  • 關注高度複雜的模塊
  • 在維護環境下,改善你手中正在處理的代碼。若是你正在維護某部分代碼,請確保代碼在離開你的時候比來以前更健康
  • 開發階段的重構是提升程序質量的最佳時機。

10、代碼調整技術(性能)

1.邏輯

  • 在知道答案後中止判斷;
  • 按照出現頻率調整判斷順序,讓運行最快和判斷爲真可能性的判斷首先執行;

2.循環

  • 將判斷外提。若是在循環運行時某個判斷結果不會改變,你就能夠把這個判斷提到循環的外面。
  • 合併。就是把兩個對同一組元素進行循環的操做合併在一塊兒,減小循環開銷。
  • 儘量減小在循環內部作的事情。若是能夠在循環外面計算某些語句,而只在循環內部使用計算結果,那麼就把該部分語句放在循環外面。

11、管理構建

1.鼓勵良好的編碼實踐幾種技術

  • 給項目的每一部分分派兩我的
  • 逐行復查代碼
  • 要求高級技術人員給代碼簽名
  • 安排一些好的代碼示例給別人看
  • 強調代碼是公共財產
  • 獎勵好代碼
  • 一份簡單的標準:「我必須能理解並閱讀這個項目裏的全部代碼」

2.編程工具

①源代碼工具

  • IDE
  • diff比較器
  • merge工具
  • 源代碼美化器
  • 代碼模板

②重構源代碼

重構器

程序庫:

Image(2)

代碼生成器

打造本身的編程工具


12、源代碼佈局與風格

1.基本原則

  • 好佈局方案的關鍵是能使程序的外觀與邏輯結構一致,也就是讓人和計算機有一樣的理解。
  • 編程工做量的一小部分是寫讓計算機能看懂的程序,一大部分是讓其餘人能看懂程序。
  • 外表悅目比其餘指標是最不重要的。

2.良好佈局的目標

  • 程序表現代碼的邏輯結構
  • 始終如一的表現代碼的邏輯結構
  • 改善可讀性
  • 經得起修改

3.佈局技術

  • 空白。能提升可讀性,如空格、製表符、換行、空行。
  • 分組。確保相關的語句成組放在一塊兒。
  • 空行。將不相關的語句分隔開。
  • 縮進。用縮進的形式顯示程序的邏輯結構。
  • 括號。對包含兩個以上的項的表達式,應該用括號去澄清。

4.控制結構的佈局

  • 不要用未縮進的begin-end對
  • 段落之間要使用空行
  • 單語句代碼段的格式要先後統一
  • 對於複雜的表達式,將條件分隔放在幾行上

5.單行語句的佈局

  • 每行只放一個語句
  • 每一個語句只進行一個操做
  • 數據聲明的佈局:
    • 每行只聲明一個變量
    • 變量聲明應儘可能接近其首次使用的位置

6.註釋的佈局

  • 註釋的縮進要與相應代碼一致
  • 每行註釋至少用一個空行分開

7.子程序的佈局

  • 用空行分隔子程序的各部分
  • 將子程序參數按照標準縮進

8.類的佈局

  • 一個文件應只有一個類
  • 文件的命名應與類名有關
  • 在文件中清晰的分隔子程序,至少使用兩個空行

十3、自說明代碼

1.編程風格作文檔

在代碼層文檔中起做用的因素並非註釋,而是好的編程風格。對於精心編寫的代碼而言,註釋只是精美外衣的小飾物而已。

代碼易讀性的最高水平:自說明代碼。

2.高效註釋之關鍵

  • 採用不會打斷或抑制修改的註釋風格
  • 用高層次的僞代碼減小注釋時間
  • 將註釋集成到你的開發風格中

3.註釋技術

①行尾註釋

  • 不要對單行代碼作行尾註釋
  • 行尾註釋可用於數據聲明

②代碼塊註釋

  • 註釋應表達代碼的意圖
  • 註釋代碼時應注重 爲什麼作(why) 而不是 怎麼作(how)
  • 用註釋爲後面的內容作鋪墊
  • 說明很是規作法。
  • 將主次註釋區分開。在次要註釋前加省略號,主要註釋以正常方式編排

③註釋聲明數據

對數值聲明的註釋應標明其單位;


十4、軟件工藝的話題

1.征服複雜度:

軟件設計與構建的 主要目標就是征服複雜性。

2.代碼可讀性

首先是爲人寫程序,其次纔是爲機器

3.深刻一門語言去編程,而不是浮於表面

4.藉助規範集中注意力

規範是一套用於管理複雜度的智力工具。

5.基於問題域編程

  • 儘量工做於最高的抽象層次。
  • 將程序劃分爲不一樣的抽象層次。
相關文章
相關標籤/搜索