程式碼整潔之道讀書記

小諾哥發表於2018-12-23

有意義的命名

軟體程式設計中命名隨處可見, 如函式, 引數, 類名, 變數, 包名, 檔名等。一個好的命名能夠望名知意, 方便後續的維護。

下面是一些基本的關於命名的規則:

  • 命名語意化: 有意義的命名能夠替代註釋

  • 避免誤導性命名

    1. 命名外形上的相似
    如 數字0與字母O同時出現   變數xyzControllerForOrderOfSetting和xyzControllerForLoginSetting(需要花時間去區分)
    
    2. 語義廢話,含混不清的命名
    如 同一個模組出現這樣的方法或者命名(需要花時間去區分). getUserInfo/getUserData/getUser, userInfo/userData/user
    
    複製程式碼
  • 多使用能夠讀的出來的名稱: 避免自造詞, 多使用合乎規範的英文單詞

  • 使用易搜尋的名稱

    1. 易搜尋指的是在海量程式碼中快速定位到該命名
    2. 以單個字母命名的名稱僅適用於短方法中的本地變數(如js中d(document),w(window))
    3. 命名的長短應該與作用域大小成對應關係
    複製程式碼
  • 類名

    類名與物件名應該是名詞或者名詞短語, 避免使用Processor, UserData等,類名不應該是動詞
    複製程式碼
  • 方法名

    方法名應該是動詞或者動詞短語
    屬性訪問器,屬性修改器,斷言等應該加上get, set, is等字首
    複製程式碼
  • 每個概念對應一個詞, 並且一以貫之

    舉例說明:
    比如你在一個類裡面的同型別方法都是使用get作為字首, 但是在另外一個類裡面的方法又是使用fetch作為字首。這就是沒有保持一個概念一個詞。
    
    另外就是保持你的程式碼風格統一性
    複製程式碼
  • 避免使用雙關語

    避免同一個單詞用於不同的目的,同一個術語用於不同的概念
    複製程式碼
  • 多使用大家達成統一認識的領域名稱(術語)

    舉例說明
    比如使用visitor(訪問者)而不是accounrVistor
    Queue/jobQueue
    複製程式碼
  • 新增有意義的語境

    大多數時候我們是沒法通過命名達到自我說明, 這個時候就需要新增適當的語境來方便我們理解。
    新增語境的方式就是給命名新增字首。
    createXxxx / addXxx / deleteXxx / updateXxx
    複製程式碼
  • 避免新增無意義的語境

    當短名稱足夠描述清楚時候, 要優於長名稱
    複製程式碼

    如何寫好函式

  • 短小

    函式應該短小,不能太長, 20行封頂
    複製程式碼
  • 程式碼塊和縮排

    if語句,else語句,while語句,switch/case中子句等, 其中的程式碼塊應該只有一行,該行也應該是一個函式呼叫語句。
    例如:
    if (true) {
        // 函式呼叫
    } else {
        // 函式呼叫
    }
    複製程式碼
  • 一個函式應該只做一件事

    當你的函式不能再被拆開一個函式時候就標示做了一件事
    複製程式碼
  • 一個函式一個抽象層級(抽象邏輯塊)

    程式碼應該保持一個自頂向下的閱讀順序。
    每一個函式後面儘可能緊跟下一個抽象層級的函式
    複製程式碼
  • switch語句

    switch/case語句有多個子句時候,可以把switch語句置於抽象工廠中,不對外暴露,然後工廠方法中針對不同的case語句建立不同的實體
    複製程式碼

程式碼整潔之道讀書記

  • 使用描述性的名稱

  • 函式引數

    1. 函式引數個數: 理想情況函式引數個數依次為0,1,2,超過兩個應該避免
    2. 當函式需要三個或者超過三個以上引數時候, 推薦把一些物件封裝為類
    3. 當我們需要傳入個數可變的引數時候, 可以使用引數列表
    
    複製程式碼
  • 動詞與關鍵詞結合

  • 對於一元函式時候, 我們可以使用動詞與關鍵詞結果方式來更好表述該函式的作用。
    舉例:
    writeField(name): => 修改欄位name
    複製程式碼
  • 無副作用

    雖然我們說函式只做一件事, 但是常常會隱式的做一些其他事情,導致異常的發生, 尤其像動態語言(Python,JavaScipt), 沒有型別約束, 一不小心就修改了物件型別。
    
    避免使用輸出引數, 如果引數必須要修改某種狀態,索性就修改所屬物件的狀態
    複製程式碼
  • 分隔指令與詢問

    函式要麼做什麼事情,要麼回答什麼事情,兩者不可兼得。即
    函式要麼修改某物件的狀態, 要麼返回該物件的有關資訊
    複製程式碼
  • 使用異常替代返回錯誤碼

    舉例:
    一個函式deletePage(page)用錯誤碼標示執行的結果: E_OK / E_ERROR
    如果你的程式碼中大量採用該風格的函式, 有時候會導致大量的if巢狀。
    
    if (deletePage(page) == E_OK) {
        if (deletePerson(person) == E_OK) {
            
        } else {
            
        }
    } else {
        
    }
    
    我們應該使用異常替代返回錯誤碼的方式,這樣錯誤處理程式碼就能把程式碼進行分離
    
    try (
    	// 主路徑程式碼
    ) catch () {
        // 錯誤處理
    }
    複製程式碼
  • 抽離try/catch程式碼塊

    函式應該只做一件事, 錯誤處理就是一件事 
    複製程式碼
  • DRY原則: 別重複自己

    消除重複 => 提取程式碼中能複用的模組, 複用的類, 複用的方法等
    複製程式碼

註釋

與其給糟糕的程式碼新增註釋不如重寫
複製程式碼

註釋最大的隱患在於隨著存在時間越久, 距離其所描述的程式碼越遠, 所以對於程式設計師來說,應該時刻保持註釋與程式碼的同步。

  • 註釋不能美化糟糕的程式碼

    與其為糟糕的,難以理解的程式碼寫註釋不如花時間重寫程式碼
    複製程式碼
  • 用程式碼來替代註釋闡述內容

  • 好註釋

    1. 提供資訊的註釋: 比如檔案註釋, 類註釋, 函式註釋等
    2. 闡述: 當我們無法通過引數或者返回值來描述程式碼內容時候需要通過註釋來描述
    3. 警示類註釋: 提醒後面維護者可能出現的結果
    4. TODO註釋: 描述你未來要做的工作列表
    5. 編寫公共的api註釋文件
    複製程式碼
  • 壞註釋

    1. 多餘的註釋: 無法提供比程式碼本身提供更多的資訊, 或者說讀註釋並不比讀程式碼效果好
    2. 誤導性註釋: 你的註釋不夠精確, 甚至本身就有錯誤
    3. 循規式註釋(這個仁者見仁智者見智): 作者以java為例每個函式都要有javadoc是不可取的,pyhon其實也有文件字串的約定
    4. 日誌式註釋: 記錄程式碼變更或者程式碼log複製程式碼
  • 對於不再需要的註釋直接刪除而不是原地註釋掉, 會對後續維護者產生誤導

相關文章