代码整洁笔记——高质量代码的命名法则

1.0 高质量代码的命名法则

1.1名副其实

名副其实说起来貌似很简单,但真正做起来,似乎没那么容易。选个好名字要花一些时间,但其实选好名字之后省下来的时间,要比之前选名字时花掉的时间多得多。

我们一旦发现有更好的名称时,就应该换掉之前的旧名称,这样做读你代码的人(包括你自己),都会很开心。

一个好的变量、函数或类的名称应该已经几乎答复了所有的大问题。它应该告诉你,这个名称所代表的内容,为什么会存在,做了什么事情,应该如何用等。

如果一个名称需要注释来补充才能让大家明白其真正含义,那其实就不算是名副其实。(并不是说不需要注释,恰如其分的注释是程序员让自己代码锦上添花的好方法。)

以下的这句代码里的d就不算是个好命名。名称d什么都没说,它没引起我们对时间消逝的感觉,更别说单位是天了:

int d; // elapsed time in days||经过了几天时间

我们应该选择这样的指明了计量对象和计量单位的名称:

int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;

1.2避免造成误导

我们应该避免留下隐藏代码本意的错误线索,也应该避免使用与本意相悖的词。例如,别用accountList来指一组账号,除非它真的是List类型,用accountGroup、bunchOfAccounts,或者直接用accounts,都是更好的选择。

尽量提防长得太像的名称。想区分XYZControllerForEfficientHandlingOfStrings和XYZControllerForEfficientStorageOfStrings,会花费我们太多的时间。因为这两个词,实在太相似了。

以同样的方式拼写出同样的概念才是信息,拼写前后不一致就是误导。

1.3尽量做有意义的区分

  1. 尽量避免使用数字系列命名(a1、a2…….aN)。这样的名称纯属误导,因为很多时候完全没有提供正确的信息,没有提供导向作者意图的线索。
  2. 废话是另一种没有意义的区分。如果我们有一个Product类,还有一个ProductInfo或ProductData类,那么他们的名称虽然不同,但意思却无区别。这里的Info、Data就像a、an和the一样,是意义含混的废话。

注意,只要体现出有意义的区分,使用a、the这样的前缀就没错。例如,将a用在域内变量,把the用于函数参数。

1.4尽量使用读得出来的名称

我们要使用读得出来的名称。如果名称读不出来,讨论的时候就会不方便且很尴尬,甚至让旁人觉得很蠢。

例如,变量名称是beeceearrthreecee,讨论的时候读起来简直像没吃药。

1.5尽量使用可搜索的名称

单字母和数字常量有个问题,就是很难再一大篇文字中找出来。

找MAX_CLASSED_PER_STUDENT很容易,但想找数字7,就很麻烦。

同样,字母e也不是个便于搜索的好变量名。因为作为英文中最常用的字母,在每个程序、每段代码中都有可能出现。

名称长短应与其作用域大小相对应,若变量或常量可能在代码中多处使用,应赋予其以便于搜索的名称。

举个栗子,比较如下两段代码:

for (int j=0; j<34; j++)
{
    s += (t[j]*4)/5;
}
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++)
{
    int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
    int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
    sum += realTaskWeeks;
}

按整洁代码的要求来评判,第一段代码会让读者不知所云,第二段代码比第一段好太多。第二段代码中,sum并非特别有用的名称,但至少他搜索得到。采用能表达意图的名称,貌似拉长了函数代码,但要想想看,WORK_DAYS_PER_WEEK要比数字5好找得多,而列表中也只剩下了体现我们意图的名称。

1.6 取名不要绕弯子

我们取名的时候要避免思维映射,不应当让读者在脑中把你的名称翻译为他们熟知的名称,也就是说取名不要绕弯子,而是要直白,直截了当。

在多数情况下,单字母不是个好的命名选择,除非是在作用域小、没有名称冲突的地方,比如循环。循环计数器自然有可能被命名为i,j或k(最好别用字母l),这是因为传统上我们惯用单字母名称做循环计数器。

程序员通常都是聪明人,聪明人有时会借助脑筋急转弯炫耀其聪明。而聪明程序员和专业程序员之间的区别在于,专业程序员了解,明确就是王道。专业的程序员善用其能,能编写出其他人能理解的代码。

1.7 类名尽量用名词

类名尽量用名词或名词短语,比如Customer, WikiPage,Account, 或 AddressParser。

类名最好不要是动词。

1.8 方法名尽量用动词

方法名尽量用动词或动词短语。比如postPayment, deletePage, 或者save。

属性访问器、修改器和断言应该根据其value来命名,并根据标准加上get、set和is前缀。

举个栗子,这里的getName、setName等命名都很OK:

string name = employee.getName();
customer.setName("mike");
if (paycheck.isPosted())...

而重载构造器时,使用描述了参数的静态工厂方法名。如:

Complex fulcrumPoint =Complex.FromRealNumber(666.0);

通常好于:

Complex fulcrumPoint = new Complex(666.0);

我们也可以考虑将相应的构造器设置为private,强制使用这种命名手段。

1.9 每个概念对应一词,并一以贯之

我们需给每个概念选一个词,并且一以贯之。

例如,使用fetch、retrieve和get来给在多个类中的同种方法命名,你怎么记得住哪个类中是哪个方法呢?

同样,在同一堆代码中混用controller、manager,driver,就会令人困惑。DeviceManager和Protocol-Controller之间有何根本区别?为什么不全用controller或者manager?他们都是Driver吗?这就会让读者以为这两个对象是不同的类型,也分属不同的类。

所以,对于那些会用到你代码的程序员,一以贯之的命名法简直就是天降福音。

1.10 通俗易懂

我们应尽力写出易于理解的变量名,把代码写得让别人能一目了然,而不必让人去非常费力地去揣摩其含义。我们想要那种大众化的作者尽责地写清楚的通俗易懂的畅销书风格,而不是那种学者学院风的晦涩论文写作风格。

1.11 尽情使用解决方案领域专业术语

记住,只有程序员才会读你写的代码。所以,尽管去用那些计算机科学(Computer Science,CS)领域的专业术语、算法名、模式名、数学术语。

对于熟悉访问者(Visitor)模式的程序来说,名称AccountVisitor富有意义。给技术性的事物取个恰如其分的技术性名称,通常就是最靠谱的做法。

1.12 添加有意义的语境

很少有名称是可以自我说明的。所以,我们需要用有良好命名的类,函数或名称空间来放置名称,给读者提供语境。若没能提供放置的地方,还可以给名称添加前缀。

举个栗子,假如我们有名为firstName、lastName、street、houseNumber、city、state和zipcode的变量。当他们搁一块儿的时候,的确是构成了一个地址。不过,假如只是在某个方法中看到一个孤零零的state呢?我们会推断这个变量是地址的一部分吗?

我们可以添加前缀addrFirstName、addrLastName、addrState等,以此提供语境。至少,读者可以知道这些变量是某个更大变量的一部分。当然,更好的方案是创建名为Address的类。这样,即便是编译器也会知道这些变量是隶属于某个更大的概念了。

另外,只要短名称足够好,对含义的表达足够清除,就要比长名称更合适。添加有意义的语境甚好,别给名称添加不必要的语境。

2.0总结

  • 要名副其实:一个好的变量、函数或类的名称应该已经答复了所有的大问题。一个好名称可以大概告诉你这个名称所代表的内容,为什么会存在,做了什么事情,应该如何用等。
  • 要避免误导:我们应该避免留下隐藏代码本意的错误线索,也应该避免使用与本意相悖的词。
  • 尽量做有意义的区分:尽量避免使用数字系列命名(a1、a2…….aN)和没有意义的区分。
  • 尽量使用读得出来的名称:如名称读不出来,讨论的时候会不方便且很尴尬。
  • 尽量使用可搜索的名称:名称长短应与其作用域大小相对应,若变量或常量可能在代码中多处使用,应赋予其以便于搜索的名称。
  • 取名不要绕弯子:取名要直白,要直截了当,明确就是王道。
  • 类名尽量用名词:类名尽量用名词或名词短语,最好不要是动词。
  • 方法名尽量用动词:方法名尽量用动词或动词短语。
  • 每个概念对应一词,并一以贯之:对于那些会用到你代码的程序员,一以贯之的命名法简直就是天降福音。
  • 通俗易懂:应尽力写出易于理解的变量名,要把代码写得让别人能一目了然,而不必让人去非常费力地去揣摩其含义。
  • 尽情使用解决方案领域专业术语:尽管去用那些计算机科学领域的专业术语、算法名、模式名、数学术语。
  • 要添加有意义的语境:需要用有良好命名的类,函数或名称空间来放置名称,给读者提供语境。若没能提供放置的地方,还可以给名称添加前缀。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容