1. 程式人生 > >[學習筆記] 《程式碼整潔之道》(一)

[學習筆記] 《程式碼整潔之道》(一)

[學習筆記] 《程式碼整潔之道》—第1章 整潔程式碼

  • 程式設計:將需求明確到機器可以執行的細節程度 —> 程式碼
  • 保持程式碼整潔讓營地比你來時更乾淨!

[學習筆記]《程式碼整潔之道》—第2章 有意義的命名

名副其實

  • 說起來簡單,但這是很嚴肅的事!

    • 選個好名字要花時間,但省下更多的時間。
    • 注意命名,一但發現更好的,就換掉舊的。
  • 變數,函式或類的名稱

    • 已經答覆了所有大問題
      • 它為什麼存在
      • 它做什麼事
      • 應該怎麼用
    • 如果名稱需要註釋來補充,那就不算是名副其實!
  • 選擇指明瞭計量物件和計量單位的名稱,如:

int d; //消逝的時間,以日計

//更好的名稱
int elapsedTimeInDays;
int daysSinceCreation; int daysSinceModification; int fileAgeInDays;
  • 選擇體現本意的名稱能讓人更容易理解和修改程式碼。

避免誤導

  • 必須避免留下掩藏程式碼本意的錯誤線索。
    • 應當避免使用與本意相悖的詞;
    • 提防使用不同之處較小的名稱;
      • ControllerForEffectientHandingOfString 和 ControllerForEffectientHandingOfString難以快速區分。
    • 拼寫前後不一致就是誤導
      • 以同樣的方式拼寫出同樣的概念才是資訊。

做有意義的區分

  • 如果程式設計師只是為滿足編譯器或者直譯器的需要而寫程式碼,就會製造麻煩!

  • 如果名稱必須相異,那其意思也應該不同!

  • 以數字系列命名()是依義命名的對立面

    • 純屬誤導

    • 完全沒有提供正確的資訊

    • 完全沒有提供導向作者意圖的線索

      public static void copyChars(char a1[], char a2[]){
          for(int i = 0; i < a1.length; i++){
              a2[i] = a1[i];
          }
      }
      
      //修改後就像樣許多
      public static void copyChars(char source[], char destination[]){
          for(int i = 0;
      i < source.length; i++){ destination[i] = source[i]; } }
  • 廢話是另一種沒有意義的區分

    • Product 類,ProductData 類, ProductInfo 類;名稱雖然不同,但意思去無區別!
    • 廢話就是冗餘。
  • 要區分名稱,就要以讀者能鑑別不同之處的方式來區分。

使用讀的出來的名稱

  • 人類擅長於記憶和使用單詞,單詞能讀出來。

    class DtaRcrd102{
        private Date gentmdhms;
        private Date modymdhms;
        private final String pszqint = "102";
        /* ... */
    };
    
    //修改後
    class Customer{
        private Date generationTimestamp;
        private Date modificationTimestamp;
        private final String recordId = "102";
        /* ... */
    };
    

使用可搜尋的名稱

  • 單字母名稱和數字常量,很難在一大篇文字中找出來。

    • MAX_CLASSES_PER_STUDENT 很容易找;
    • 數字 7 就很難找。
  • 名稱的長短應與其作用域的大小相對應

    • 若變數或常量可能在程式碼中多次使用,則應賦其以便於搜尋的名稱;
    • 竊以為單字母名稱用於短方法中的本地變數。
    for(int j=0; j<34; j++){
        s += (t[j]*4)/5;
    }
    
    //修改後
    int realDaysPerIdealDay = 4;
    const int WORK_DAYS_PER_WEEK = 5;
    int sum = 0;
    for(int j=0; j < NUMBER_OF_TASKS; j++){
        int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
        int realTaskWeels = (realdays / WORK_DAYS_PER_WEEK);
        sum += realTaskWeeks;
    }
    

避免使用編碼

  • 把型別或作用域編進名稱裡,頭然增加了解碼負擔。
  • 不必用 m_字首來標明成員變數。
    • 應當把類做得足夠小,消除對成員字首的需要。
  • ???介面和實現

避免思維對映

不應當讓讀者在腦海中把你的名稱翻譯為他們熟知的名稱。

  • 聰明的程式設計師和專業的程式設計師之間的區別在於
    • 專業的程式設計師瞭解,明確是王道
    • 專業的程式設計師善用其能,編寫其他人能理解的程式碼。

類名

  • 類名和物件名應該是名詞名詞短語

    • 如 Customer,WikiPage,Account 和 AddressParser。
    • 避免使用Manager, Processor,Data 或 Info 這樣的類名。
  • 類名不應該是動詞

方法名

  • 方法名應該是動詞或者動詞短語
    • 如 postPayment,deletePage 或 save。
  • 屬性訪問器、修改器和斷言應該根據其值命名,依標準加上get, set 和 is 字首。

別扮可愛

  • 意到言到,言到意到,別耍寶!

每個概念對應一個詞

  • 給每個概念選一個詞,並且一以貫之。
  • 函式命名應當獨一無二,而且保持一致。

別用雙關語

  • 避免將同一單詞用於不用目的。
  • 同一術語用於不同概念,基本就是雙關語了。

使用解決方案領域名稱

  • 只有程式設計師才會讀你的程式碼!
    • 儘管用那些家算計科學術語、演算法名、模式名、數學術語。

使用源自所涉問題領域的名稱

  • 如果不能用程式設計師熟悉的術語來命名,就採用所涉問題領域而來的名稱吧。
  • 優秀的程式設計師與設計師,其工作之一就是分離解決方案領域問題領域的概念。
    • 與所涉問題領域更為貼近的程式碼,應當採用源自問題領域的名稱。

新增有意義的語境

  • 很少有名稱是能夠自我說明的——多數都不能。
    • 你需要有良好命名的類、函式或名稱空間來放置名稱,給讀者提供語境。
    • 給名字條件加字首就是最後一招
      • 可以新增字首 addrFirstName、addrLastName、addrState等,以此提供語境。
      • 更好的方案是建立名為 Address 的類。

不要新增沒用的語境

  • 只要短名稱足夠清楚,就比長名稱好。
  • 別給名稱新增不必要的語境。
  • 命名的要點就是精確

取好名字最難的地方在於需要良好的描述技巧和共有文化背景

參考文獻

[1] Robert C. Martin 著,韓磊 譯,《程式碼整潔之道》,北京:人民郵電出版社,2010.1(2018.9 重印), ISBN 978-7-115-21687-8。