《編寫可讀代碼的藝術》我的總結

【北京】 IT技術人員面對面試、跳槽、升職等問題,如何快速成長,得到大廠入門資格和升職加薪的籌碼?與大廠技術大牛面對面交流,解答你的疑惑。《從職場小白到技術總監成長之路:個人職場焦慮與救贖》活動連接: 碼客

恭喜fpx,新王登基,lpl*b 咱們是冠軍程序員

強烈安利一本書《編寫可讀代碼的藝術》,一個程序猿寫好的代碼很重要。這篇文章是這本書的讀後總結,從此我也會根據本身實際開發中的領域添加、修改這篇文章。面試

代碼應該易於理解

  1. 寫代碼的關鍵思想是代碼應當易於理解,也就算代碼的寫法應當使別人理解它所需的事件最小化。
  2. 減小代碼行數是一個目標,但把理解代碼的時間最小化更重要。絕大多數狀況這兩個目標是不衝突的。
  3. 代碼並非越小越好,例如三元運算符能夠簡化代碼縮小行數,可是濫用可能致使代碼理解時間增加。

第一部分:表面層次

命名規範

  1. 名字表示對應信息,詞語應更富有表現力。例如:
單詞 更多選擇
send deliver、dispatch、announce、distribute、route
find search、extract、locate、recover
make create、set up、build、generate、compose、add、new
  1. 避免像 tmp 和 retval、foo 這樣無心義的詞,可是若是隻是爲了臨時存儲變量、做用域只在幾行以內,用這樣的詞命名也無可厚非。
  2. 循環迭代器中的 i、j、iter 和 it 等作索引很空泛,建議用有意義的名字,好比 user_i、member_j 或者直接 ui、mj 之類。
  3. 用具體的名字替代抽象的名字,且爲名字附帶更多的信息。例如 id,若是 id 的類型重要的話,能夠改成 hex_id;變量若是是度量的話帶上單位是個好習慣,例如:start_ms,progress_ms 之類
函數 參數名更好的選擇
start(int delay) delay_secs
createCache(int size) size_mb
throttleDownload(float limit) limit_kbps
rotate(float angle) degrees_cw

注意:並不該該給程序中的沒一個變量都加上一堆的屬性,僅在須要的地方加上,注意咱們的主旨:代碼應該易於理解。編程

  1. 變量名並非越長越好,做用域短的變量名字能夠儘可能簡單;若是一個變量做用域很大,則應儘可能包含更多的信息。
  2. 須要注意的,變量函數命名應儘可能簡單(這和上面並不衝突),在包含儘可能多的信息下儘可能簡單。convertToString() 就不如 toString(),doServeLoop() 就不如簡單的 serveLoop()

注意:須要注意的是,命名的主旨:把信息塞入名字中。所作的一切都是爲了讓代碼更好的理解。性能優化

總結:1.使用專業的名字;2.避免空泛的名字;3.使用具體的名字進行描述;4.爲變量增長細節;5.做用域大的變量使用更詳細的名字函數

不會誤解的名字

命名應該三思:這個名字會被別人解讀成其餘含義麼?oop

  1. 推薦用 min 和 max 表示極限、first 和 last 表示包含的範圍,begin 和 end 表示包含、排除的範圍。

例如,購物車最大容量,cart_too_big_limit 建議改成 max_items_in_cart,一樣的命名還有 begin_index、end_index 之類佈局

  1. 命名不要誤導使用者。例如:get 和 size 方法通常認爲是個輕量方法,全部在 get 方法中儘可能不要作複雜、代價沉重的操做。若是有,請換個名字,例如:getPage() 能夠換爲 downloadPage() 之類。

總結:變量命名應儘可能準確無誤解。性能

審美

  1. 使用一致的佈局(有一個前同事常常隨意換行、隨意空格,他的代碼簡直逼死強迫症)
  2. 讓類似的代碼看上去類似(這個能夠理解爲,類似代碼,經過行對齊和列對齊讓它看上去一致)
  3. 相關代碼分組造成代碼塊
  4. 代碼的順序儘可能有意義。例如,有一堆變量,能夠按重要性進行排序,也能夠按字母順序進5. 行排序,也能夠根據具體邏輯和業務場景進行排序。

風格的一致性。大括號放在命名後面仍是單獨換行都行,可是必定要保持一致。須要注意的是:一致的風格比「正確」的風格更重要。學習

註釋

註釋應該儘可能幫助讀者理解代碼的用意優化

不要寫不須要的註釋(不要給很差的命名添加註釋,能迅速推斷的事實也不須要註釋)
用代碼記錄思想:

爲代碼添加評論,記錄「坑點」和「陷阱」;

2.爲代碼中的瑕疵添加註釋(例如:「// TODO:處理 JPEG 之外的圖像格式」) 標記 | 一般的意義 -------- | --- TODO: | 我尚未處理的事情 FIXME: | 已知沒法運行的代碼 HACK: | 對一個問題不得不採用的比較粗糙的解決方案 XXX: | 危險!這裏有重要問題
爲常量添加註釋,代表取這個常量具體數值的意義

3.站在讀者的角度去思考他們須要知道些什麼。
爲讀者答疑解惑,解釋意料以外的行爲。
全局觀註釋和總結性註釋,給整個類、模塊、函數塊添加註釋解釋模塊運做,加強讀者理解,不至於迷失在細節中。

寫出言簡意賅的註釋

如下的寫註釋的技巧
// TODO

第二部分:代碼邏輯優化

把控制流變得易讀

關鍵思想:把條件、循環和其餘對控制流的改變作的越「天然」越好,運用一種方式使讀者不用停下來重讀你的代碼。

  1. 條件語句中參數的位置:變量在左側,常量在右側。if (length >= 10) 優於 if (10 <= length)

有的時候應爲擔憂漏寫一個"="而寫出 if (obj = NULL) 的 bug,程序員會把順序調換一下爲 if (NULL = obj),這是沒有必要的,現代的編譯器對於這種問題基本都有警告。

  1. if/else 語句塊的順序 if/else 裏的語言遵循以下順序:
  • 優先處理正邏輯而不是負邏輯
  • 先處理簡單的狀況,讓 if 和 else 在整個屏幕內均可見
  • 先處理有趣和可疑的狀況。「有趣」意味着更關心的狀況、或者更符合認知的狀況,可疑則意味着一些異常狀況

上面三個規則並無優先級,有時可能會衝突,具體採用哪一種就要程序員本身判斷了

  1. 三目運算符能夠縮減代碼行數,可是可能會增長代碼複雜度。

追求最小代碼行數,更好的度量方法是最小化人們理解它所需的時間。

  1. 避免 do/while 循環。do/while 循環將條件放在代碼的最後面違反了常規的認知,並且寫 do/while 循環語句不是那麼必要,反正我從沒寫過。
  2. 從函數中提早返回。有些程序員認爲函數中不該該出現多條 return 語言,這是不對的,提早返回沒有問題,並且能提升代碼可讀性。 有的時候程序員很容易寫出多層嵌套、多個 if 條件嵌套的代碼,在這種狀況下提前 return 就頗有必要。

拆分超長的表達式

關鍵思想:把超長的表達式拆分紅更容易理解的小塊。

  1. 添加「解釋變量」。if line.split(':')[0].strip() == "root" 改成 username = line.split(':')[0].strip(),if username == 「root」,就是這個意思。
  2. 用德摩根定理操做邏輯表達式,例如 if (!(a && b) 改成 if (!a || !b), if (!(a || b) 改成 if (!a && !b) 更容易簡潔。
  3. 複雜的邏輯條件應當拆分爲小的語句。 if 語句中應該儘可能不要超過兩個值,能夠用上面的提早 return 返回進行優化。

變量和可讀性

關於變量有三個問題:

  1. 變量越多就越難追蹤它們的動向
  2. 變量的做用域越大追蹤動向花的時間越久

3變量改動的越頻繁越難追蹤它的當前值
做 爲程序員很煩看到一段程序定義了一堆大做用域的變量,而後處處賦值。 全部關於變量有以下規則:

  1. 減小變量,減小程序的中間結果
  2. 縮小變量的做用域,變量應該對儘可能少的代碼可見。訪問控制越嚴格越好。

有些編程規範喜歡將變量定義在函數和語句塊的頂端,這會強迫讀者立刻思考這些變量,但這些變量要好久後纔會用到,這是不對的。

  1. 變量應該儘可能少的修改,只寫一次的變量最好。

第三部分:從新組織代碼

抽取不相關的子問題

一句話:一個函數一個類應該只幹一件事,不相干的問題應該抽取到獨立函數獨立類中。但要注意的是,凡事過猶不及,過分拆分可能致使程序中過多的小函數,這個度由程序員把握。

一次只作一件事

和上面同樣:應該把代碼組織得一次只作一件事。

把想法變成代碼

這一章難以總結,建議直接看書領悟。
// TODO

少寫代碼

嘿嘿,最好讀的代碼就是沒有代碼。

  1. 不要過分設計
  2. 從新考慮需求,解決版本最簡單的問題,能完成工做就行。和上一條同樣的目的,不要過分設計。
  3. 常常性通讀標準庫整個 API,保持一個熟悉程度。

該書最後給出了兩個實際的項目問題,寫的很好,建議看看。

這本書寫的不錯,建議花個一兩天時間看一遍。 最近在讀《iOS 和 macOS 性能優化》這本書,有時間的話寫篇技術總結。

(想自學習編程的小夥伴請搜索圈T社區,更多行業相關資訊更有行業相關免費視頻教程。徹底免費哦!)

相關文章
相關標籤/搜索