好名字——能看出方法特征的名字才是好名字

无名天地之始,有名万物之母——《道德经》 名字是一切的开始,名字是一个东西的缩影。在程序里面,命名也总是一个难题。

 

数据来源:https://ubuntuforums.org/showthread.php?t=690304

 

我统计了一下项目代码中方法都是用什么开头的,统计时仅包含Java代码,不包括测试代码

这里统计了某产品的所有Java项目面代码,不包括测试代码,多数工程使用了lombok。

 

从上面的图看,命名还是很多样的。一般情况下命名挺简单的,但是我还是看到了好多这样的方法

  • void getAllMatchedGeo() // 得到的Geo信息在哪里呀?

  • void setE2eRpk()             // 我怎么把Rpk的数据给你呀?

看似简单的命名,还是出现了让人困惑的东西。其实我们常用的get、set、from、to,其实都各自有个字的意思,这些词和参数组合起来必须可以表达完整的意思,才算是命名正确。下面是一些我对命名的想法:

 

按照场景分类

获取信息类方法

获取信息类方法一定有返回值

前缀 语义 例子 是否耗时 返回对象是否同一个
get 拿到一个已经存在的数据,如果没有找到不抛出异常 String getName()
String getNameByCode(String code)
不耗时,一般和属性对应,直接读取 相同条件得到的对象应该是同一个
create 创建一个新的对象 List<AbstractCriteria> createWeeklyCriteria(QueryContext context) 有相对复杂的逻辑,耗时 每次返回的都是新对象
find 在给定的列表中或者自身的数据中找到某个符合条件的对象,如果没有找到不抛出异常 String findLatestVersion(Set<String> versions) 逻辑比get复杂 相同条件得到的对象应该是同一个

错误的例子

  1. void getAllMatchedGeo()。没有返回值

  2. 复杂逻辑放在get中,方法使用者可能会错误的使用这个方法影响效率。

    Country getCountry(String code) {
        ...
        return new Country(....);
    }

    建议修改名称为Country createCountry(String code)

  3. Date getStartInWeek(Date date)

    从一个日期计算这个日期所在的周,然后取这个周的第一天。这是一个复杂的逻辑,建议不使用get,改为calculateStartInWeek

配置类方法

配置类方法一定会有输入参数,可以有返回值,返回原来的值

前缀 语义 例子 是否耗时
set 设置参数 void setName(String name)
String setParam(String name, String value)
不耗时,一般和属性对应
init 初始化某些信息,可以没有参数 void initIndex()
void initParam(String name, String value)
比set的逻辑复杂,可能耗时,一般只调用一次
config 配置某些信息,一般有参数 void configRequiredColumn(Collection<String> columns) 比set的逻辑复杂,可能耗时,可以多次调用

错误的例子

  1. void setE2eRpk()。读者不知道set的数据是什么,建议修改名称为initE2eRpk(),表示通过对象上的已有信息初始化或者直接进行无参数初始化。

转换类方法

转换类方法一定有返回值

前缀 语义 例子 是否耗时 返回对象是否同一个
to 将当前对象或者参数转换为其他类型,一般转换前后对象具有相同含义,只是类型变了 DateRange toDateRange() 逻辑简单,不耗时,不报错 每次都新建一个对象
from 将某个对象的信息转换为当前类型,一般转换前后对象具有相同含义,或者具有组成关系 WeeklyDTO from(Weekly data) 逻辑简单,不耗时,不报错 每次都新建一个对象
parse 从复杂的字符串或数据中解析出数据 Map<String, Object> parseResponse(String responseJson)
Object JSON.parseObject(String json)
逻辑复杂,耗时,可能报错,建议通过异常报错 每次都新建一个对象
of 一般在享元模式中,根据key值找到享元对象,是静态方法
也用于表示在一个整体中取一部分
ZoneId of(String zoneId)
Enum.valueOf(String name)
SheetAgency of(Workbook workbook, String sheetName)
可以只是检索过程,也可以有初始化过程,初始化的结果会被缓存 相同的key会得到相同的结果
convert 从一种表现形式转换成另一种表现形式 BigDecimal convertWeightToKg(String weightUnit, String weight) 有点耗时 每次都新建一个对象

 

其他

  • load/save

    成对出现,表示从IO读取和写入IO

  • read/write

    成对出现,表示从IO读取和写入IO

  • 方法名称要精简

    类似方法名称为parseExcelAndCheck,其实解析Excel一定会检测Excel格式是否有效,因此这里的AndCheck很多余,建议直接命名为parseExcel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章