变量名起得烂,debug火葬场
第二章讲"有意义的命名",这章读得我频频点头——谁没在"到底变量a是用户ID还是订单号"这种问题上浪费过时间呢?
命名的核心:不用注释也能懂
作者说"名称需要答复所有大问题:为什么存在?做什么?怎么用?"。想想自己写的代码:
int d; // 天数
这不就是典型的反面教材吗?改成elapsedTimeInDays,哪怕过半年看,也能一眼明白。
想起之前维护过的一段代码,里面全是list1、flag、data这种名字。每次改功能都得先花半小时猜变量含义——命名的懒惰,最终会变成debug的勤快。
那些坑人的命名习惯,你中了几个?
- 用了误导性的词:把数组叫
accountList,结果里面放的是Set - 名字太像:
XYZControllerForEfficientHandling和XYZControllerForEfficientStorage,肉眼根本分不清 - 加无意义的前缀后缀:
m_、obj、Info,纯属画蛇添足 - 用拼音+英文混搭:
shangpinList、userMingzi,读起来像绕口令
最绝的是看到有人用l(小写L)和O(大写O)当变量名,跟1和0长得一模一样,调试时差点把人看瞎。
好名字的秘诀:读得出来,搜得到
- 读得出来:
generateUserToken比genUsrTkn好太多,开会讨论时不用尴尬地念"梗恩-厄斯额-提肯" - 搜得到:
MAX_ORDER_COUNT比7容易找,全局改配置时不会漏 - 跟业务走:在支付系统里,
paymentDeadline比timeLimit更明确 - 别玩梗:
deleteUser就好,别叫killUser,新来的同事可能真会慌
想起之前把"用户登录次数"命名为userLoginCount,后来产品加了"失败登录次数",直接加userFailedLoginCount就行,特别清晰。这就是作者说的"每个概念对应一个词"。
命名的终极考验:脱离上下文也能懂
书中有个例子特别经典:
// 烂代码
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
// 好代码
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
改完之后,哪怕不看注释,也知道这是在扫雷游戏里找被标记的格子。好的命名能把隐藏的上下文暴露出来。
(下一章要讲函数了,想起自己写过的500行长函数,有点瑟瑟发抖...)