天天看点

代码优化(一):Java代码命名规范

编程中最难的事情 —— 命名!

怎么做好命名规范,这里结合了项目,分成四个等级。为以下:

  • 基础:命名风格
  • 第一级:精准命名,体现意图
  • 第二级:用业务语写代码
  • 第三级:编写符合英语语法规则的代码

基础:命名风格

每个公司都有自己的命名风格,比较有名的就是阿里开源的《阿里巴巴Java开发手册泰山版》,非常推荐去官网下载阅读。

像不要用中文、拼音、缩写这些很常见的就不说了;这里结合个人的项目,摘取了一些容易被忽视的规范,审视一下是否已经中招:

  1. 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类 命名以它要测试的类的名称开始,以 Test 结尾
  2. 布尔类型的变量,不要加is前缀,否则部分框架会引起序列化错误
  3. 如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。(OrderFactory,LoginProxy,ResourceObserver)
  4. 接口的方法不要加修饰符(public也不要加)
  5. 各层命名规范

    a. Service/DAO 层方法命名规约

    • 获取单个对象的方法用 get 做前缀
    • 获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects
    • 获取统计值的方法用 count 做前缀
    • 插入的方法用 save/insert 做前缀
    • 删除的方法用 remove/delete 做前缀
    • 修改的方法用 update 做前缀
    b. 领域模型命名规约
    • 数据对象:xxxDO,xxx 即为数据表名
    • 数据传输对象:xxxDTO,xxx 为业务领域相关的名称
    • 展示对象:xxxVO,xxx 一般为网页名称
    • POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO

第一级:精准命名,体现意图

通过前面命名风格,至少保证了代码符合了规范,但是并不一定是一个好的命名。好的命名首先要实现精准命名。

什么是非精准命名呢?举个反例:

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);
}
           
  • 方法名processChapter(处理章节): ”处理章节“是一个大的动作描述,可以是”开始处理章节“,”中止处理章节“,”添加章节内容“等等;具体做了什么,还是要看代码逻辑。
  • 改成changeChapterToTranlsating(将章节修改为翻译中):方法名描述了代码逻辑的细节。但是封装代码的重要原因就是 不想暴漏那么多细节,使用者只要知道这个方法是干嘛用的。
  • 改成startTranslation(开启翻译):正确命名,描述意图,非细节,是一个好的命名

业务层面的不精准,这种不精准比较难发现,属于高级坏味道:

//表示用户id为userId,但是不够精准,在这个场景下用户扮演的角色是审核人
public void approveChapter(long chapterId, long userId) {
	...
}

//审核人角色的用户id所以用reviewerUserId
public void approveChapter(long chapterId, long reviewerUserId) {
	...
}
           

第二级:用业务语写代码

什么叫做用业务语写代码,首先先了解一下它的对立面:用技术语写代码

List<Book> bookList = service.getBooks();
           
  • bookList,List是技术语,如果给到非技术人员,可能并不理解其含义
  • xxxList、xxxMap、xxxSet:种基于实现细节的命名方式,如果修改返回类型,变量名是不一定会修改
  • 好的命名应该是业务语,如:books

技术名词的出现,代表它缺少一个应有的模型,如redis

//命名出现了redis
Book cachedBook = redisBookStore.get(isbn);
//redis  改为 cache,好一点,但是cache也是技术术语
Book cachedBook = cache.get(isbn);
           

spring较好的处理方式,添加Annotation

@Cacheable("books")
public Book getByIsbn(String isbn) {
...
}
           

以上讨论的是基于业务类的项目,尽可能使用业务语言;但是对于技术类的项目,技术名称就是它的业务语言,这就另当别论了。

第三级:编写符合英语语法规则的代码

错别字满天飞的文章,很难让人相信是一篇好文章。阿里开发手册也说明了:

  • 不要用拼音写代码
  • 不要用单词首字母,或者一部分
  • 不要用无意义的字母做变量

...

这里讨论的是 命名的语法结构 和 准确用词:

  1. 命名的语法结构
    • 类名应该为名词,表示一个对象。
    • 方法名 为 动词 或 动宾,表示一个动作
    举两个反例:
    • completedTranslate(完成翻译)不是有效的动宾,要把“完成”译为 complete,“翻译”用成它的名词形式 translation,所以应改为completeTranslation(动词+名词)
    • retranslation(重新翻译)不是动词,改为retranslate
  2. 准确用词

    首先就是拼写错误,可以借助IDE的typo拼写错误检查。

    代码优化(一):Java代码命名规范

    再者是用词错误:例如 "审核" ,如果直接翻译,可能 得到 audit,review两个词。那到底用那个词呢?audit更有官方味道,更适合审计。review更符合审核的场景。

    要解决这个问题,建议建立团队的业务词汇表,规定常用词汇。如下:

    名称 英文 说明
    作品 Book 作者创作的作品
    章节 Chapter 作品的一部分
    审核 review 审核方对作品内容进行查看的过程
    审核通过 approve 审核方对作品内容予以通过
    审核未通过 reject 审核方对作品内容不予通过

参考资料:

  • 阿里巴巴Java开发手册泰山版
  • 极客时间-代码之丑