第一部分 表面层次的改进
代码的可读性最直观的表现就是在表面层次上,比如良好的格式,好的变量、函数名字,合理的注释等等。这些地方很容易修改,应用起来比较方便,所以学习编写可读代码的艺术,首先从表层入手,打造一个优美的颜值。
第二章 把信息装进名字里
在编码过程中,不论是变量还是函数,如果可能的话,代码应该越少越好,应该让变量和函数通过名字达到自注释的能力,这就要求我们,要把信息装进名字中。
1、选择专业的词
在我们命名一个函数或是变量时,应该尽量选择专业的词。比如下面的这个例子,
def GetPage(url): ...
get这个词并没有什么有用的信息,我们通过这个名字,根本就不能弄清楚,这个函数是从本地的缓存中得到一个页面,还是从数据库中,还是从互联网中?这个时候我们要避免使用这种中性的词语,不要忌惮写长函数名,应该尽量将这个函数的作用描述清楚,比如:DownloadPage(),就可以直观的推测,是从互联网中获取页面。
再看另外一个例子,
class BinaryTree
{
int Size();
}
我们期望size()函数返回什么呢?是树的高度,还是节点数,还是所占的空间?更专业的词可以是Height(),NumNodes()或者MemoryBytes()。
使用更专业的词有助于我们直观的了解代码,比如,线程的函数stop(),这个函数是停止这个线程还是暂停呢?如果是停止,是不是命名为kill()更好些,如果是暂停,也许命名为Pause()更合适。
不同的语境我们需要谨慎地选择合适的词,这样我们的代码将更有助于阅读。
2、清晰和精确比装可爱好
一般而言,tmp、retval和foo这样的名字往往是想不出名字时的最佳选择,但是这种名字经常会掩盖掉变量的真实意义,让我们阅读代码时不得不更加小心。
大多数情况下,如果一个变量只是作为短期使用,只起到临时存储的作用,并没有什么实际意义的话,我们可以使用这些空泛的词,比如:
if(left < right)
{
tmp = right;
right = left;
left = tmp;
}
retval += v[i];
第一
段代码中,tmp没有任何意义,只是作为短期使用,这样没有什么问题,并且还额外传递给我们这样的信息,其实更有助于我们阅读,会提醒我们,不用关注这个变量。
第二段代码中,retval也没有办法提示我们它的意思是什么,远不如sum_squares += v[i];中,sum_squares更有意义。
另外在多层循环中,也有这种情况,比如,要循环两层,外层是长度,内层是宽度。如果用i,j的话,容易使阅读者陷入到时刻谨记i,j的麻烦中。这种情况下,不如将循环因子定义为length,width更合适。
在良好的编码风格中,要谨慎使用i,j,tmp这种空泛的名字。
3、用具体的名字代替抽象的名字
在给变量、函数或是其他元素命名时,要把它描述的更具体而不是更抽象。
比如有一个函数叫ServerCanStart(),该函数要监听某个给定的端口。这个名字就有些抽象,太概括,从名字中不能确定它做了哪些事,如果改成CanListenOnPort()就更具体了,代码阅读者可以从名字中就可以了解它具体做了哪些工作。
4、给名字带上重要的细节
我们期望的良好的代码中,变量或是函数的名字能够做到自注释,使得阅读者从名字中就尽可能的得到更多的信息。比如下面这个例子。
在代码中,我们常常需要用到时间类变量。比如time_start,time_end,这个命名是否还能改进呢?在不同的使用中,有时候需要关注这些变量的单位,如果没有注释指明的话,使用者需要追朔这些变量的来源,来确定这些变量的单位是什么。如果我们在编码时,就讲单位写进名字里的话,比如叫time_start_ms,time_end_ms,这样一眼就能看出来这些变量是以毫秒为单位的。
类似的情况还有很多,比方说day、month或者是year,kbps、bytes和bit等等,变量往往都有其某些重要的属性,如果能在名字中,将这些重要属性显示出来的话,可读性会大大提高。
通过特殊的约定将一些属性表现出来,也是通用的做法,常见的这类表示方法有很多,比如p代表指针,c代表char,str代表string等等。
5、名字应该有多长
有时候在编码时,往往会在名字的长度上犹豫不决。太短了,不能完整地表示含义,太长的话,会显得啰嗦,也不容易看。
合理的把握名字的长度,也是一个重要的练习目标。
一般而言,不要用让人费解的一个或两个字母的名字来命名在几屏之间都可见的变量,对于这种变量,可以将名字定长些,好详细的描述其意义。对于只存在几行之间的变量,用短一点的名字更好。
6、有目的地使用大小写、下划线等
有时候我们可以通过特定的格式,来表达一些特定的含义。
比如用下划线‘_’来表示底层函数或是内部函数,用大写表示常量,对于静态函数,采用统一的名字前缀等方法,都是这种情况。
良好的风格不仅有助于提高代码的可读性,也有助于整个团队对项目的统一协作,比如新老员工的交替。