好名字——能看出方法特征的名字才是好名字
无名天地之始,有名万物之母——《道德经》 名字是一切的开始,名字是一个东西的缩影。在程序里面,命名也总是一个难题。
数据来源: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复杂 | 相同条件得到的对象应该是同一个 |
错误的例子
-
void getAllMatchedGeo()。没有返回值
-
复杂逻辑放在get中,方法使用者可能会错误的使用这个方法影响效率。
Country getCountry(String code) { ... return new Country(....); }
建议修改名称为Country createCountry(String code)
-
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的逻辑复杂,可能耗时,可以多次调用 |
错误的例子
-
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
推荐阅读