《代码之丑》学习笔记01——如何精准命名?

最近在学习 郑晔 在极客时间上的一个专栏《代码之丑》,并根据自身情况整理了一份笔记

01 | 缺乏业务含义的命名:如何精准命名?

例如这样一段代码:

public void processChapter(long chapterId) {
  Chapter chapter = this.repository.findByChapterId(chapterId);
  if (chapter == null) {
    throw new IllegalArgumentException("Unknown chapter [" + chapterId + "]"); 
  }
  
  chapter.setTranslationState(TranslationState.TRANSLATING);
  this.repository.save(chapter);
}

经过阅读我们发现,这段代码做的就是把一个章节的翻译状态改成翻译中,但是我们需要读完代码的细节才知道这段代码的意思。

data、info、flag、process、handle、build、maintain、manage、modify等等。这些名字都属于典型的过于宽泛的名字

processChapter(处理章节)的命名过于宽泛,不能精准描述,这是很多代码在命名上存在的严重问题,也是代码难以理解的根源所在。

1.命名要能够描述出这段代码在做的事情。

这段代码在做的事情就是“将章节修改为翻译中”。那是不是它就应该叫 changeChapterToTranslating呢?

2.一个好的名字应该描述意图,而非细节。

就这段代码而言, 我们为什么要把翻译状态修改成翻译中,这一定是有原因的,也就是意图。具体到这里的业务,我们把翻译状态修改成翻译中,是因为我们在这里开启了一个翻译的过程。所以,这段函数应该命名 startTranslation

最终修改为:

public void startTranslation(long chapterId) {
  Chapter chapter = this.repository.findByChapterId(chapterId);
  if (chapter == null) {
    throw new IllegalArgumentException("Unknown chapter [" + chapterId + "]"); 
  }
  
  chapter.setTranslationState(TranslationState.TRANSLATING);
  this.repository.save(chapter);
}

3.不要用技术术语命名

例如:

List<Book> bookList = service.getBooks();

这个 bookList 变量之所以叫 bookList,原因就是它声明的类型是 List。

比如,如果我发现,我现在需要的是一个不重复的作品集合,也就是说,我需要把这个变量的类型从 List 改成 Set。变量类型你一定会改,但变量名你会改吗?这还真不一定,一旦出现遗忘,就会出现一个奇特的现象,一个叫 bookList 的变量,它的类型是一个 Set。这样,一个新的混淆就此产生了。

因为接口是稳定的,而实现是易变的。 我们需要一个更面向意图的名字。其实,我们在这段代码里真正要表达的是拿到了一堆书,所以,这个名字可以命名成 books

List<Book> books = service.getBooks();

虽然这里我们只是以变量为例说明了以技术术语命名存在的问题,事实上,在实际的代码中,技术名词的出现,往往就代表着它缺少了一个应有的模型。

在一个技术类的项目中,这些技术术语其实就是它的业务语言。但对于业务项目,这个说法就必须重新审视了。

4.用业务语言写代码

编写可维护的代码要使用业务语言,例如以下一段代码

public void approveChapter(long chapterId, long userId) {
  ...
}

这个函数的意图是,确认章节内容审核通过。这里有一个问题,chapterId 是审核章节的 ID,这个没问题,但 userId 是什么呢?了解了一下背景,我们才知道,之所以这里要有一个 userId,是因为这里需要记录一下审核人的信息,这个 userId 就是审核人的 userId。你看,通过业务的分析,我们会发现,这个 userId 并不是一个好的命名,因为它还需要更多的解释,更好的命名是 reviewerUserId,之所以起这个名字,因为这个用户在这个场景下扮演的角色是审核人(Reviewer)。

public void approveChapter(long chapterId, long reviewerUserId) {
  ...
}

从某种意义上来说,这个坏味道也是一种不精准的命名,但它不是那种一眼可见的坏味道,而是需要在业务层面上再进行讨论,所以,它是一种更高级的坏味道。

总结

好的命名要体现出这段代码在做的事情,而无需展开代码了解其中的细节,这是最低的要求。再进一步,好的命名要准确地体现意图,而不是实现细节。更高的要求是,用业务语言写代码。

如果今天的内容你只能记住一件事,那请记住:好的命名,是体现业务含义的命名

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值