首页 > 代码库 > <The Art of Readable Code> 笔记二 (上)

<The Art of Readable Code> 笔记二 (上)

第1章  封装信息到名字 (Packing information into names)

1  use specific words

  GetPage() 不如 FetchPage() 和 DownloadPage() 更具体

  BinaryTree 类中的 Size() 不如 Height()、NumNodes() 或 MemoryBytes() 更明确

class BinaryTree {
  int Size();
  ...        
}

  同理,Thread 类中的 通常是 Kill(),而不是 Stop(),并且一般 Pause() 和 Resume() 成对出现

class Thread {
  void  Stop();
  ...          
}

  一些常用词语的替代词

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

 

2  avoid generic names

1) retval

  下面的 retval 求的是 “平方和”,因此,用 sum_squares 代替更为合适

var euclidean_norm = function (v) {
    var retval = 0.0;
    for (var i = 0; i < v.length; i += 1)
        retval += v[i] * v[i];
    return Math.sqrt(retval);
};

2) tmp

  以下是 tmp 合适的例子

if (right < left) {
    tmp = right;
    right = left;
    left = tmp;
}

  但是,下面这个 tmp 就不如改为 user_info 了

String tmp = user.name();
tmp += " " + user.phone_number();
tmp += " " + user.email();
...
template.set("user_info", tmp);

 同样,下面的 tmp_file 也比 tmp 更为明确

tmp_file = tempfile.NamedTemporaryFile()
...
SaveDate(tmp_file, ...)

 3) i, j, k

    i, j, k 非常容易混淆,不如改为 clubs_i, members_i, users_i 方便,再次简化为 ci, mi, ui

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;

 

3  use concrete names

   例如,当监听端口时, ServerCanStart() 是抽象的,不如 CanListenOnPort() 具体

   c++ 中,谷歌为了避免编译器自动生成 拷贝构造函数 或 赋值算子时,使用了如下宏:

class ClassName {
private:
    DISALLOW_EVIL_CONSTRUCTORS(ClassName);
public:
    ...
};

  其定义为:

#define DISALLOW_EVIL_CONSTRUCTORS(ClassName) \
  ClassName(const ClassName&);   void operator=(const ClassName&);

  实际上,这个名字并不好,不如 DISALLOW_COPY_AND_ASSIGN(ClassName)  贴切

 

<The Art of Readable Code> 笔记二 (上)