天天看點

《編寫可讀性代碼的藝術》摘錄總結

重溫《編寫可讀性代碼的藝術》,記下的部分摘錄和總結,以便日後回顧、反思

摘錄&總結

宗旨

  • 可讀性基本定理總是優先于其他條例或原則
  • 盡管減少代碼行數是一個好目标,但把了解代碼所需的時間最小化是一個更好的目标
  • 寫出新的團隊成員能了解代碼(命名同樣适用)

命名

  • 選擇專業的詞,避免空泛或意義模糊的名字
  • 用具體的名字代替抽象的名字
  • 給名字帶上附加資訊(如機關 MB、KB)
  • 為作用域更大的命名取一個更長(更詳細)的名字
  • 采用一緻的命名規範,有目的的使用大小寫和下劃線
    • 對不同實體使用不同格式就像文法高亮一樣,能幫你更容易的閱讀代碼
    • google c++命名規範中,常量的格式是

      kConstantName

      而不是

      CONSTANT_NAME

      ,目的是與宏區分開來,類成員變量使用下劃線結尾,如

      offset_

      ,與普通局部變量區分開來
  • 命名應該符合使用者的期望
    • get

      length

      size

      等命名的方法,使用者期望調用它們是沒有什麼代價的(不會耗費性能)
  • 變量和方法定義選擇一個有意義的順序,始終一緻的使用它

注釋

  • 好名字比好注釋更加重要
  • 幫助讀者能夠 更容易 了解代碼的是好注釋
  • 不要為那些從代碼本身就能 快速 推斷的事實寫注釋
  • 如果有注釋能夠比沒有注釋了解起來 快很多,那麼注釋是有可以的
    • name = '*'.join(line.split('*')[:2]) # 丢棄第二個'*'後面的所有東西

  • 加入“導演評論”
    • # 出乎意料的是,對于這些資料用二叉樹比用哈希表快40%

    • # 哈希運算得代價比左/右比較大得多

    • 防止讀者為了無謂的優化而浪費時間
    • # 作為整體可能丢掉幾個詞,這沒有什麼問題。要100%解決太難了

    • 解釋了自己的解決方法雖然有瑕疵,但并不影響正常使用,并表示自己未能找到完美的方案,不鼓勵他人在此作無謂的優化
  • 意料之中的提問,大部分人會産生疑惑的地方(為什麼這麼做,為什麼直接用簡單的方法)應該寫上注釋
  • 公布可能的陷阱
    • 連接配接失敗一段時間後逾時異常
    • 性能問題,運作時間達到 O(num*depth), 嵌套很深的輸入需要小心
  • 全局觀注釋
  • 總結性注釋
    • 這種注釋也是對函數(或一段代碼)所做的事情的總結,在讀者深入了解細節之前就能得到該代碼的主旨

控制流

  • 把條件、循環以及其他對控制流的改變做得越自然越好(往往自然語言表述出來就是自然的,嘗試先用自然語言描述邏輯)
  • 邏輯處理順序,有時這些傾向性會沖突,那麼你就需要自己判斷哪一種情況應該優先處理了,很多情況下這都會有很明确的選擇
    • 先處理掉簡單的情況(例如先處理特殊情況,提前傳回,減少分支數量)
    • 先處理有趣的或者可疑的情況
    • 先處理正邏輯
  • 三目運算符應該不會對可讀性造成負面影響的情況下使用
  • 使用解釋變量,用它來表示一個子表達式,提高可讀性
  • 使用德摩根定理
    • not (a or b or c) == (not a) and (not b) and (not c)

    • not (a and b and c) == (not a) or (not b) or (not c)

  • 嘗試從“反方向”解決問題

變量

  • 消除中間變量(對可讀性沒有影響的變量)
  • 縮小變量作用域
  • 隻寫一次的變量更好

組織代碼

  • 建立大量通用代碼,把一般代碼和項目專有代碼分開
  • 積極地發現并抽取出不相關的子邏輯
    • 看看某個代碼塊,問問自己:這段代碼的高層次目标是什麼?
    • 對每一行代碼,問一下:它是直接為目标工作的嗎?這段代碼的高層次目标是什麼?
    • 如果足夠的行數在解決不相關的子問題,抽取代碼到獨立的函數中
  • 簡化已有接口
  • 把一個方法中的所有操作保持在同一個抽象層次上
  • 一次隻做一件事
    • 列出代碼所做的所有“任務”
    • 盡量把這件任務拆分到不同的函數中,或者至少是代碼中不同段落中
  • 最好讀的代碼就是沒有代碼
  • 讓你的代碼庫越小、越輕量級越好
    • 建立越多越好的“工具”代碼來減少重複代碼
    • 減少無用代碼或沒有用的功能
    • 讓你的項目保持分開的子項目狀态

測試

  • 使測試易于閱讀和維護
  • 讓錯誤資訊具有可讀性
    • python中的unittest子產品的assertEqual方法比assert的錯誤資訊更具體

總結

  • 寫代碼時,應該時常問下自己:新的團隊成員能否了解自己的代碼
  • 所謂的工程學就是關于把大問題拆分成小問題,再把這些問題的解決方案放回一起
  • 為代碼增加一個函數存在一個小的(卻有形的)可讀性代價(你需要暫時跳到另一個函數中去,你回來之後可能會忘了些什麼)
  • 一段代碼抽出成一個函數的準則是:這樣做是否提高了可讀性,如果目前并不關注于這段代碼的細節,那麼是應該抽成一個函數的
  • 一次隻做一件事,先列出方法要做的任務,盡量保持一個方法中的操作在同一個抽象層次上
  • 先用自然語言描述邏輯

繼續閱讀