如何精准命名

如何精准命名

避免命名过于宽泛

案例1

1
2
3
4
5
6
7
8
9
10

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);
}
  • 问题:命名过于宽泛,不能精准描述,只有阅读这段代码,才可以知道这段代码做了什么。

  • 修正:具体到这里的业务,其实是把翻译状态改为了翻译中,是因为我们在这里开启了一个翻译过程,所以这段代码应该命名为satrtTranslation

类似的:data,info,handle,build,maintain,modify等等,都是过于宽泛的名词

一个好的名字,应该描述意图,而不是细节。

避免使用技术术语命名

案例1

1
List<Book> bookList = service.getBooks();
  • 问题:这是一种基于实现的命名,编程的一个重要原则是面向接口编程。即接口是稳定的,实现是易变的。假设这里我现在需要的是一个不重复的作品集合,也就是说这里需要把List改成Set,变量类型一定会改,但是你不一定会记得改变量名,一旦遗忘,就会出现一个bookList变量,它的类型是set,就会产生混淆。
  • 修正:这里要表达的是拿到一堆书,所以这个命名改为books。

案例2

1
2
3
4
5
6
7
8
9
10
public Book getByIsbn(String isbn) {
Book cachedBook = redisBookStore.get(isbn);
if (cachedBook != null) {
return cachedBook;
}

Book book = doGetByIsbn(isbn);
redisBookStore.put(isbn, book);
return book;
}
  • 问题:这段代码里直接出现了redis,通常来说这里真正需要的只是一个缓存,redi s只是一种实现

缓存只是一种技术术语,不应该出现在业务代码中

程序猿之所以喜欢用技术语言去命名,是因为程序员写代码很大程度上会参考别人写的代码,而行业里比较优秀的一些代码,往往是一些开源的技术项目。

在一个技术类项目里,这些技术术语其实就是他们的业务语言,但是在业务项目里,这个说法就要另当别论了。

避免违反语法规则的命名

案例1

1
2
3
4
5
public void completedTranslate(final List<ChapterId> chapterIds) {
List<Chapter> chapters = repository.findByChapterIdIn(chapterIds);
chapters.forEach(Chapter::completedTranslate);
repository.saveAll(chapters);
}

问题:completedTranslate不是一个正常的英语函数名

修正: completeTranslation

常见的命名规则是:类是一个名词,表示一个对象。方法名是一个动词或者是动宾短语,表示一个动作。

另外还有两个常见的坏味道这里就不举例了。

  • 不准确的英语词汇(对于业务上会用到的一些名词,可以整个团队一起,建立一个业务词汇表,用集体的智慧)
  • 单词拼写错误

用业务语言写代码

案例1

1
2
3
4

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

问题:这个函数的意图是确认章节通过,chapterId是章节id,但是userId是什么?了解了背景才知道这里是需要记录下审核人的信息,这个userId就是审核人的userId,

修正:因为用户在这个场景下的身份是审核人,所以修改userId为reviewerUserId

好的命名,是体现业务含义的命名。


如何精准命名
http://example.com/代码之丑学习笔记/
作者
Panyurou
发布于
2022年3月27日
许可协议