Please enable Javascript to view the contents

程序员的底层思维:为什么命名这么难?

 ·  ☕ 6 分钟

There are only two hard things in computer science: cache invalidation and naming things.

计算机科学中只有两件难事:缓存失效和命名。

——(Phil Karlton)菲尔·卡尔顿

两件难事

Phil Karlton

菲尔·卡尔顿 (Phil Karlton) 是一个著名的计算机科学家,他曾在 Netscape 平台工作。


最近在读张建飞老师的《程序员的底层思维》(值得一读,推荐),重点强调了程序员的抽象思维,让我想起了 Phil Karlton 的这句话。今天就来聊聊命名。

《程序员的底层思维》

程序员的底层思维 (豆瓣)

命名重要且难

正如Stack Overflow的创始人Joel Spolsky所说:

“Creating good names is hard,but it should be hard,because a great name captures essential meaning in just one or two words.”(起一个好名字应该很难,因为,一个好名字需要把要义浓缩在一到两个词中。)

命名为什么难呢?因为命名的过程本身就是一个抽象和思考的过程,在工作中,当我们不能给一个模块、一个对象、一个函数,甚至一个变量找到合适的名称的时候,往往说明我们对问题的理解还不够透彻,需要重新去挖掘问题的本质,对问题域进行重新分析和抽象,有时还要调整设计和重构代码。因此,好的命名是我们写出好代码的基础。

因此,要想真正做好命名,除了要掌握一些命名技法,还需要更深层次的修炼——提升抽象思维能力。

以下总结命名错误的几个层次、原因及规避方法。

拼音命名

许多新手喜欢用拼音来命名,比如shujukunihaoshijieccgc,我不说中文(数据库、你好世界、存储过程),你肯定是看不懂的。这种方式弊端很多,比如:

  • 拼音是有语调的,同音词太多,没办法做到唯一性,也就无法保证命名的准确性;
  • 中文词语很简洁,但拼音往往很长,不分词根本没法读,如果加下划线分词,那就更长了;
  • 中文不区分动词和名词,容易造成功能性的命名,如submit和submission,中文都是tijiao;
  • 中文拼音不好区别单数和复数;
  • 中文也不好区分主动和被动,比如选择元素选中的元素,正常英语是SelectItemsSelectedItems,而拼音可能会写能一样的xuanzhe_yuansuxuanzhe_de_yuansu,同样,没办法表示单复数形式;

Donald Knuth 曾经说过:“Programs are meant to be ready by humans and only icidentally for computers to execute.” 代码是用来让人读的,只是顺便让机器执行而已。(原话或许是 Hal Abelson 说的)

Donald Knuth

种种原因,拼音命名是无法保证代码是可读的,也就是说,你写的代码,别人看不懂,你自己过一段时间也看不懂。所以,千万不要用拼音命名。更不要拼音和英文混用,这样更让人头大。

杀死一个程序员不用枪,只要让他维护一个拼音命名的代码库就行了。

拼写错误

拼写错误是最低级的错误。我刚参加工作时,偶尔会犯这种错误,比如:database 会写成 datebase。当然,现在这种错误很容易被 IDE 或者编译器检查出来,所以,只要你不是故意的,这种错误很难出现在正式发布的代码中。

anyway,编程就是要细心一点,如果你经常犯这种错误,那就要考虑找人结对编程,或者转行。

词不达意

虽然英语是世界通用语言,但是,毕竟不是我们的母语,有时候,我们会用错词,比如:completedfinished 都有完成的意思,且都有动词词性。但在语义侧重稍有差别。

  • complete: 在表示动词“完成”之义时,侧重于表达完成得比较圆满。另外,complete还有形容词词性,表示“完成的,完整的”。

  • finish: 在表示“完成之义时,侧重于表示”结束了,做完了”,并没有什么好坏之分。

举个例子你就明白~

  • 如果你嫁对了人, then you are complete。

  • 如果你嫁错了人, then you are finished。

  • 如果你嫁错了人还生了个倒霉孩子, then you are completely finished。

英文还有一个缺陷,就是词汇量太大。专有名词太多,同一种类型不同的命名。如汽车、火车、出租车、公交车、卡车、救护车、消防车分别叫做 Car,train,taxi,bus,truck,ambulance。

词汇量大,自然会造成记忆负担。解决办法就是多看英文资料,多学多写。

代码风格不统一

代码风格不统一,也是一种命名错误。比如,有的人喜欢用驼峰命名法,有的人喜欢用下划线命名法,有的人喜欢用帕斯卡命名法。当然这不是什么大问题,只要团队内部统一就行了。也有很多工具可以帮助我们做到风格统一,比如:EditorConfig

有时候风格不统一来自编程范式的不同,比如:面向对象编程和函数式编程。面向对象编程中,我们喜欢用名词来命名,比如:StudentTeacherClass,而函数式编程中,我们喜欢用动词来命名,比如:addremoveupdate。这种情况下,建议团队内部统一编程范式,这样,代码风格也就统一了。

命名过长

命名过长也是一种错误。限定词越多,意思不是越明确吗?其实不然,命名过长,反而会让人看不懂。

比如,有的人喜欢把变量命名成:theNumberOfStudentsInClass,这样的命名太长。事实上叫studentsCount就可以了。

解决办法是要找到核心词。比如,studentsCount,核心词是counttheNumberOfStudentsInClass,核心词是students。核心词越多,越难理解。

依赖注释

有些人函数命名很随意,然后用注释来解释函数的作用。这种做法就好像正经工作时间不好好努力,下班后加班加点的干,是极不可取的。因为,代码应该是自解释的,添加注释往往还会增加额外负担。如果你的代码需要注释,那么,你的代码就不够清晰,需要重构。

大部分注释都是无用的,当然,有些业务逻辑复杂的地方,还是需要注释的,但是,注释应该是最后的手段,而不是第一选择。

随意命名

现实情况是,很多工程师常常忽略了命名的重要性,只要能实现业务功能,名字从来就不是重点。实际上,这既是对系统的不负责任,也是对自己的不负责任,更是对后期维护系统的人不负责任。写程序和写文章有极强的相似性,本质上都是用语言阐述一件事情。试想,如果文章中用的都是一些词不达意的句子,这样的文章谁能看得懂,谁又愿意去看呢?

每一次的变量命名、方法命名、类命名都是难得的训练抽象思维的机会。不要浪费这个机会,要认真对待每一个命名,要尽可能的做到准确、简洁、易读。

总结

命名是一门学问。总体三个经验:

  • 学好英语
  • 多做练习
  • 多看优秀代码

现在人工智能工具可以帮写代码,能够大块大块的生成各种业务逻辑的代码。而代码都是基于变量名生成的,所以,写好变量名,就能生成高质量的代码。

所以,命名是程序员的基本功。即便是 AI 时代,抽象思维能力都是程序员的核心竞争力之一。

参考资料

分享

码中人
作者
码中人
Web Developer