这本书真的是详细到吓死人!这次我读的是变量的命名,Robert竟然用了14页的篇幅去介绍它!
最喜欢的一句话:问题的答案没有体现在代码段中,可那就是它们该在的地方。
回到正题,写感受最深的笔记:
1、避免误导
程序员必须避免留下掩藏代码本意的错误线索。应当避免使用于本意相背的词。例如,hp、aix和sco都不该作为变量名,因为它们都是Unix平台或者类Unix平台的专有名称。即便你是在编写三角计算程序,hp看起来是个不错的缩写,但那也会提供错误信息。
更别用accountList来指称一组帐号,除非它真的是List类型。List一词对程序员来说有特殊的意义。如果包纳帐号的并非真的是个List,就会引起错误的判断。所以,用accountGroup或bunchOfAccounts,甚至直接用accounts都会好一些。
提防使用不同之处较小的名称。想区分模块中某处的XYZControllerForEfficientHandlingOfStrings和另一处的XYZControllerForEfficientStorageOfStrings,会华多长时间呢?这两个词外形实在太相似了。
以同样的方式拼写出同样的概念才是信息。拼写前后不一致就是误导。
……
误导性名词真正可怕的例子,是用小写l和大写O作为变量名,尤其是在组合键使用的时候。当然,问题在于它们看起来完全像是常量“一”和“零”。
2、做有意义的区分
光是添加数字系列或是废话远远不够,即使这足以让编译器满意。如果名称必须相异,那其意思也应该
不同才对。
以数字系列命名(a1、a2,……,aN)是依义命名的对立面。这样的名称纯属误导——完全没有提供正确的信息;没有提供导向作者意图的线索。试看:
public static void copyChars(char a1[], char a2[])
{
for(int i = 0; i< a1.length; i++)
{
a2[i] = a1[i];
}
}
如果参数名改为source和destination,这个函数就会像样的多。
废话是另一种没有意义的区分。假设你有一个Product类。如果还有一个ProductInfo或ProductData类,那它们的名称虽然不同,意思却无区别。Info和Data就像a、an和the一样,是意义含混的废话。
注意,只要题现出有意义的区分,使用a和the这样的前缀就没错。例如,你很可能把a用在域内变量,而把the用于函数参数。但如果你已经有一个名为zork的变量,又想调用一个名为theZork的变量,麻烦就来了。
废话都是冗余。Varable一词永远不应该出现在变量名中。Table一词永远不应该出现在表名中。NameString会比Name好吗?难道Name会是一个浮点数不成?如果是这样,就触犯了关于误导的规则。设想有个名为Customer的类,还有一个名为CustomerObject的类。区别何在呢?哪一个是表示客户历史支付情况的最佳途径?
3、使用读得出来的名称
人类长于记忆和使用单词。大脑的相当一部分就是用来容纳和处理单词的。单词能读得出来。人类进化到大脑中有那么大的一块地方用来处理语言,若不善加利用,实在是种耻辱。
……
有家公司,程序里面写了个genymdhms(生成日期,年、月、日、时、分、秒),他们一般读作“gen why emm dee aich emm ess”。我有个见字照读的恶习,于是开口就念“gen-yah-mudda-hima”。后来好些设计师和分析师都有样学样,听起来傻乎乎的。我们知道典故,所以会觉得很搞笑。搞笑归搞笑,实际上在强忍糟糕的命名。在给新开发者解释变量时,他们总是读出傻乎乎的自造次,而非恰当的英语词。
……
4、成员前缀
也不必用m_前缀表明成员变量。应当把类和函数做得足够小,消除对成员前缀的需要。应当使用某种可以高亮或用颜色标出成员的编辑环境。
……
此外,人们会很快学会无视前缀(或后缀),只看到名称中有意义的部分。代码读得越多,眼中就越没有前缀。最终,前缀变作不入法眼的肥料,变作了陈旧代码的标志物。
5、类名
类名和对象名应该是名词或名词短语,如Customer、WikiPage、Account和AddressParser。避免使用Manager、Processor、Data或Info这样的类名。类名不应该是动词。
6、方法名
方法名应该是动词或动词短语,如postPayment、deletePage或save。属性访问器、修改器和断言应该根据其值命名,并依Javabean标准加上get、set和is前缀。
7、添加必要的语境
很少有名称是能自我说明的——多数都不能。反之,你需要用良好命名的类、函数或名称空间来放置名称,给读者提供语境。如果没有这么做,给名称添加前缀就是最后一招了。设想你有名为firstName、lastName、street、houseNumber、city、state和zipcode的变量。当他们搁在一块儿的时候,很明确是构成了一个地址。不过,假使只是在某个方法中看见孤零零的一个state变量呢?你会理所当然地推断那是某个地址的一部分吗?
可以添加前缀addrFirstName、addrLastName、addState等,一次提供语境。至少,读者会明白这些变量是某个更大结构的一部分。当然,更好的方案是创建名为Address的类。这样,即便是编译器也会知道这些变量隶属某个更大的概念了。
命名。。。呵呵,从来没想过的问题。翻看以前自己写的代码……自己笑都笑不出来了。这些代码,别人怎么读?