你真的会给变量命名吗?

  |   0 评论   |   0 浏览

有读者看到标题就开始敲键盘了,这还需要写个文章来水?命名不就是不能用 abc、123 这种,名字要有意义嘛,这有啥好讲的?

但现实中,虽然懂得名字要有意义,很多程序员依然无法逃离命名沼泽。

万金油命名法

看段代码:

图片

看上去不是挺正常吗?有何不可?

那我问你,这段代码在干嘛?你就得全神贯注去阅读代码细节了。已阅后,你说这段代码不就是把一个章节的翻译状态改成翻译中。

为何你得阅完这段代码细节,才知道该方法在干嘛?

问题就在方法名 - processChapter,该方法是在处理章节没错,但这名太宽泛。如果说“将章节的翻译状态改成翻译中”就叫***处理章节***,那么请问:

  • 将章节的翻译状态改成翻译完毕
  • 修改章节内容

是不是也能叫*处理章节*呢?
所以,这的确是个过于宽泛的方法名,没有大错,但
不精确

乍一看,这名字有含义,但实际却不能有效反映这段代码的具体含义。
若做的是个信息处理系统,你根本无法判断,这是个博客平台还是个图书管理系统呢?

从沟通角度看,这就不是一个有效信息表达。想理解它,需要消耗大量时间精力。

命名过于宽泛,不能精确描述,这是很多代码命名现状,也是让祖传代码难以理解的根因。

回想这些命名:data、info、flag、process、handle、build、maintain、manage、modify......

这些都属于 过于宽泛的命名,当这些名字出现在你的代码,可以肯定作者当时也没想好用啥名字,就开始随便起个万金油名字继续coding了。

扯半天,那它不能叫***处理章节***,那该叫啥?

  • 命名要能精确描述该方法在做什么
    这段代码就是“将章节改为翻译中”。那是不是该叫changeChapterToTranlsating?相比***处理章节***,这个名字已经算进步了,但也不算是个好名字,因为它更多的是在描述这段代码在做的细节。而封装一段代码成方法,就是因为我们不想知道过多细节。如果把细节平铺开来,那就和直接读代码细节没啥区别了。
  • 好名字应该描述意图,而非细节这段代码为何要将翻译状态修改成翻译中呢?一定是有所图的。把翻译状态改成翻译中,是因为我们在这里开启了一个翻译的过程。所以,这个方法应该叫startTranslation

图片

技术术语命名法

再看一段代码:

图片

这!也能有问题?我天天看到还写这种代码啊。

是的,我知道你们都在写这种风格代码,这就是另一个经典问题:技术术语命名法。

之所以叫 bookList,在于其声明类型是 List。这种命名几乎随处可见,如 xxMap、xxSet。

这也是种不费脑命名法,但这种命名却会带来很多问题,因为是基于技术实现细节的命名方式。

我们都知道面向接口编程原则,就是不要面向实现编程,因为接口是稳定的,而实现易变不稳定

大多数人只觉得该原则是针对类型的,但命名方面,也同样应该遵循。比如,我发现现在需要的是个不重复作品集合,即我得把这个变量的类型从 List 改成 Set。变量类型相信你一定会改,但变量名你会改吗?还真不一定,一旦忘了,就会出现:一个 bookList 变量,居然是Set类型!

那怎么命名呢?得有个更能表达意图的名字,这段代码表达的就是拿到一堆书,所以可以叫 books

图片

这名字更简单,也很表达意图了。

追根究底,使用技术名词,一般因为它缺少对应模型

比如,在业务代码里若直接出现 Redis:

图片

通常来说,这里真正需要的是个缓存。Redis 只是缓存模型的一个具体实现:

图片

但其实缓存这个概念也是个技术专业术语,也不应出现在业务代码中。

做得好的是 Spring,使用 Spring 时,若需要缓存,一般是加个注解:

图片

很多人爱用技术名词去命名,大多因为:

  • 熟悉的语言
  • 写代码,很多都是参考别人代码,优秀代码都是一些开源技术项目。那在一个技术类项目中,这些技术术语其实也就是它的业务语言。但对于我们的业务类项目,就不能生搬硬套了

若该部分确实就是处理一些技术,使用技术术语无可厚非,但若是在处理业务,就要尽可能规避技术术语。

像xxMap这种命名,表示映射关系,如:书id与书的映射关系,难道也不能命名为bookIdMap?

Map 表示的是个数据结构,而映射关系推荐写成 Mapping

高级点的坏味道

前面的坏味道其实本质都是同一问题:对业务理解不到位。

编写可维护的代码要使用业务语言。那如何知道自己的命名是否用的是业务语言呢?很简单,把这个词讲给PM听,看他懂是个啥不。

团队里若每个人都根据自己理解命名,就可能出现百家争鸣的命名,所以,一个良好的团队实践是建立团队的业务词汇表,统一业务命名。

当团队对业务有了一致的理解后,兴许还能发现更高级的坏味道:

图片

看方法名,应该是确认章节内容审核通过。

但我有一问,chapterId 是审核章节的 ID,这没问题,但 userId 是啥?了解背景后,才知道这里要 userId,是因为需要记录审核人信息。

通过业务的分析,就发现,这个 userId 不是个好名字,因为它还需要更多解释,更好的命名是 reviewerUserId,因为这用户在当前场景下就是审核人(Reviewer)角色。

图片

这也是一种万金油命名法,但它不是那种一眼就能看出的坏味道,而是需要在业务层进行讨论,所以,算个高级坏味道。


标题:你真的会给变量命名吗?
作者:jianzh5
地址:http://javadaily.cn/articles/2021/11/13/1636816334929.html