代码整洁之道——高质量代码命名

       记得曾经看过一篇报道说:"程序员最难攻克的关卡是:如何命名(例如:给变量,类,函数和过程命名等等"。对,你没看错,这个结果是Quora 问答网站和更早的 Ubuntu 论坛跟帖的 4500 个开发者的投票。

       只要你干过几年编程,就有可能曾经被某人糟糕的代码绊倒过,或者曾经也绊倒过他人,因为压根看不懂别人代码写的是啥,各种命名都看不懂,而且有些公司的代码还不让写注释。我记得刚入职那会,主要学习看代码,一看别人代码,心里就十万只草泥马在奔腾,这写的啥,压根不知道这个变量是啥意思,学习代码特别痛苦。因此,学习代码是我最不想做的一件事,我另可写代码,但是新员工必须经历心里十万只草泥马奔腾的过程。庆幸,最后分到了一个重新零开始写代码的一个项目,但是,自己要尽量做到不要去绊倒他人,不要让别人心里默默地骂:这烂代码谁写的????因此,学习了前辈们推荐的《Clean Code》一书,让自己尽量不去绊倒他人,然后整理整理自己所看,这样可加深自己学习的印象,以后忘记了也可以看看自己所写进行回忆。

名副其实

       名副其实说起来简单,但对于一个程序员而言还是很难的。因为选一个好的名字真的耗时间,加上项目时间催得紧,一般不会花太多时间去好好考虑命名,只要功能能满足就万事大吉。这样的结果就是,可能某开发员当时自己所写代码是啥意思,隔段时间,自己也看不懂写的什么,这莫过于是一个最大的悲哀。

       注意命名,程序员逃不掉在写代码的过程中给变量函数进行命名,而一个好的命名能让他人读你代码就是一种享受,它告诉他人,它为什么会存在,它做什么事,为什么这么用。如果所命的名字需要通过注释来补充,那就不算是名副其实了。

       例如:

int i;  /*表示索引*/

       名称 i 属于常见的一个名称,因此很能让人明白该名称的作用。当然,在变量后面加了注释,但是这也无法看出是什么的索引。我们应该指名名称具体作用:

int ueIndex;
int cellIndex;

       选择体现本意的名称能让人更容易理解和修改代码。上面的例子一看就知道本意,尽量采用英文全拼,能让人一看就懂。如果由多个单词组成的名称,采用驼峰命名形式,而不是直接多个单词组成在一起,让人无法看懂单词的意思。

      例如:

int redrock

       词汇量有限(4级都考了8次才过),想举例说明:如果两个单词不使用驼峰命名形式就容易让人误解是另外一个单词,查了好久的单词,找了一个redrock,本意是red rock,在命名时应该redRock,就知道这名称是什么意思,如果是上述例子,那么这个单词又是另外一个意思了,会让人疑惑。

        下列代码的目的何在????

for(int i = 0; i < 10; i++)
{
    if(4 == i)
        deleteIndex(i);
}

       上述代码只能明白较浅的意思,并且还比较简洁。但是,问题不在于代码是否简洁,而是代码的模糊度。同时,在上述代码中,还有魔法数字,这魔法数字的含义也让人疑惑。如果明白了上述 i 、魔法数字4和10的含义,那么进行修改,我们应该尽量避免使用魔法数字。

for(int ueIndex = 0; ueIndex < MAX_UE_NUM; ueIndex++)
{
    if(EXPETION_UE_INDEX == ueIndex)
        deleteIndex(ueIndex);
}

        只要简单改一下名称,就能让人通俗易懂代码执行了什么功能。这就是名副其实的力量。

避免误导

        程序员在命名时,就应该如同给自己孩子起名字一样,不要给男生起一个女生名字,女生起一个男生名字,例如:某珍珠,这是男生名字还是女生名字?乍眼一看,这个名字应该是女生名字,可事实却是反的,这是我身边一个男生的名字(如果他看到这博客了,会不会打死我)。因此,程序员在命名时,应该避免使用与本意相悖的名字

        尽量不要使用不同之处较小的名称,这样让他人无法一眼区分两个名称是啥意思。例如:函数deleteIndex和函数deleteIndexEx,这两个函数名区别很小了,加之函数deleteIndexEx后面Ex还是缩写,也不知道是什么意思,所以他人只能去看函数内容才能明白两者的区别。

       误导性名称真正可怕的例子,是用小写字母 l 和大写字母O作为变量名,尤其是在组合使用的时候,因为,他们看起来完全像是数字 1和0,曾经看到过一个变量名:OlUpLimit,当时真是看了很久很久,Ol是个啥?这是数字0和1吗?学习代码的过程真是心累呀。

做有意义的区分

       程序员只为了自满足或者满足功能达到编译通过而写代码,往往可能他人会读不懂。个人觉得写代码时,应该要考虑没有注释的情况下,他人能看懂自己所写代码。

       废话是另一种没意义的区分。假设你有一个Product函数,如果还有一个函数ProductInfo或ProductData,那他们的名称虽然相同,意思却无区别。Info和Data就像a、an和the一样,是意义含混的废话。

       废话都是冗余。Variable一词永远不应当出现在变量名中。Table一词永远不应当出现在表名中。如果缺少明确约定,变量moneyAmount就与money没区别,customerInfo与customer没区别,accountData与account没区别,theMessage也与message没区别。要区分名称,程序员在命名时就应该站在他人能鉴别的方式来命名,而不是讲究随手改改名字,避免重定义错误发生,例如:

getActiveAccount();
getActiveAccounts();
getActiveAccountInfo();
getActiveAccountData();

        上述函数名肯定不会出现重定义错误,但是让他人如何区分,应该使用哪个函数呢???

使用读得出来的名称

        个人觉得,在每个公司的程序中应该都有缩写名称或者谐音数字,例如:数字2,谐音表示to,数字4,谐音表示for,这些发音差不多,还能理解,如果程序里面写了个genymdhms(生产日期,年、月、日、时、分、秒),他们一般读作"gen why emm dee aich emm ess",对于有见字照读的习惯,于是可以开口就年"-yah-mudda-hims"。这样会使得给新开发者解释变量的意义时,他们总是读书傻乎乎的自造词,而非恰当的英语词。

使用可搜索的名称

        这一点是深有体会,查名称导致匹配的名称太多,无法分清具体哪一个,最后得一个一个去查看匹配的名称,分辨具体哪一个才是自己需要查找的。导致这种结果的根本原因是因为:名称太短,匹配度极高。就如同生活中自己的姓名一样,查找两个字的姓名,肯定撞名率特高,在程序代码中也是如此,例如在代码中找某一个数字,它可能是某些文件名或其他常量定义的一部分,出现在因不同意图而采用的各种表达式中。因此,名称长短应与其作用域大小相对应。

结构体名 or 类名

        结构体名/类名和对象名应该是名词名词短语,如:Customer、WikiPage、Account和AddressParse。避免使用Manager、Processor、Data或Info这样的类名。类名不应当是动词

函数名 or 方法名

        函数名/方法名应当是动词动词短语,如:postPayment、deletePage或save。

 

未完待续......

你可能感兴趣的:(Clean,Code)