2013年1月4日 星期五

如何命名變數以及函式名稱

  • 命名要精準

    • 命名要精準,不要使用模糊的單字
    • def GetPage(url):
      
    • Get是一個不好得命名,沒有明確指出從什麼地方GetPage
    • 如果是從Internet,應命名為FetchPage()或DownloadPage()
    • class BinaryTree:
          def Size(self):
              ...
      
    • Size是一個不好得命名,沒有明確指出是tree的高度還是有多少個nodes
    • 直接命名為Height()或是NumNodes()會比較明確

  • 找尋更能表達意義的單字

    • 使用字典找尋適合的單字
    • 以下是一些colorful word的範例,=>左手邊的單字可用右手邊的單字取代
    • send => deliver, dispatch, announce, distribute, route
    • find => search, extract, locate, recover
    • start => launch, create, begin, open
    • make => create, set up, build, generate, compose, add, new

  • 避免tmp和retval這類通用的命名

    • 讀者沒辦法從retval中獲得更多資訊,使用更清楚的命名取代retval
    • tmp只適合用在很短生存範圍的程式碼,例如下列swapping範例tmp生存範圍只在if{}內
    • if (right < left) {
          tmp = right;
          right = left;
          left = tmp;
      }
      

  • Loop Iterator

    • iterator的名稱使用i, j, k是OK的,因為這是大家都習慣的用法
    • for (int i = 0; i < clubs.size(); i++)
          for (int j = 0; j < clubs[i].members.size(); j++)
              for (int k = 0; k < users.size(); k++)
                  if (clubs[i].members[k] == users[j])
                      cout << "user[" << j << "] is in club[" << i << "]" << endl;
      }
      
    • 最好在i, j, k前加入prefix的字串,用來辨別iterator所走訪的物件
    • if (clubs[ci].members[mi] == users[ui])
      
    • 如此一來有bug就能即時發現
    • if (clubs[ci].members[ui] == users[mi]) # Bug! First letters don't match up.
      

  • 數值和單位

    • 在命名數值變數時可以加上單位
    • Start(int delay); 
      CreateCache(int size); 
      ThrottleDownload(float limit); 
      Rotate(float angle); 
      
      Start(int delay_secs); 
      CreateCache(int size_mb);
      ThrottleDownload(float max_kbps); 
      Rotate(float degrees_cw); 
      
    • 第二個範例會比第一個範例好

  • 命名要包含資料狀態

    • 加入目前資料的狀態到命名
    • password : plaintext_password
    • comment : unescaped_comment
    • html : html_utf8
    • data : data_urlenc
  • 在短生存範圍內可使用簡短的命名

    • 變數m只出現在if的範圍內,不影響其他人理解這段程式碼
    • if (debug) {
          map<string,int> m;
          LookUpNamesNumbers(&m);
          Print(m);
      }
      

  • 不使用不常見的縮寫

    • 用BEManager取代BackEndManager並不是一個好得命名
    • 團隊新來的成員沒辦法搞懂這些縮寫

  • 刪除多餘的命名

    • ConvertToString() => ToString()
    • DoServeLoop() => ServeLoop()

  • 使用命名格式來區分不同意義

    • const, macro, class, private variable都有不同的命名格式,方便一眼區分
    • static const int kMaxOpenFiles = 100;
      class LogReader {
        public:
          void OpenFile(string local_file);
        private:
          int offset_;
          DISALLOW_COPY_AND_ASSIGN(LogReader);
      };
      

    沒有留言:

    張貼留言