选个好名字需要花时间,但省下的时间更多。
一旦发现有更好的名字,就换掉旧的。
名副其实
名称应该已经答复了所有的大问题,如它为什么会存在,它做什么,怎么用。尽量让名字不需要注释来补充解释说明。
例1
public List<int[]> getThem(){ List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) if(x[0] == 4) list1.add(x); return list1; }
代码足够简洁了,但意思却很模糊。
此为扫雷程序,theList是盘面,每个单元格都用一个简单数组表示,零下标表示状态值,4 表示“已标记”。
public List<int[]> getFlaggedCells(){ List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell: gameBoard) if (cell[STATUS_VALUE == FLAGGED) flaggedCells.add(cell); return flaggedCells; }
避免误导
除非它真的是List类型,否则别用accountList表示一组账号,用accountGroup
XYZControllerForEfficientHandlingOfStrings与XYZControllerForEfficientStorageOfStrings很相似,容易混淆。但这种以同样的方式拼写同样的概念的命名方式配合线代编辑环境的代码自动补全功能可以很大程度地方便编程。需要做好权衡,用XYZControllerForEfficientStringsHandling和XYZControllerForEfficientStringsStorage,将差异点放在末尾,让差异更明显,减小混淆。如果放至末尾很别扭,就只好保留,编程时多注意。
做有意义的区分
要区分名称,就要以读者能鉴别不同之处的方式来划分。
避免以数字序列命名
public static void copyChars(char a1[], char a2[]){ for(int i =0; i< al.length;i++){ a2[i] = a1[i] } }
应该将参数名改为source和destination
public static vod copyChars(char source[], char destination[]){ for(int i = 0;i<al.length;i++){ destination[i] = source[i]; }
避免废话
ProductInfo或ProductData名称虽不同,意思却相同,都是Product。变量aDog、theDog都是dog。
避免使用类型、作用域编码
Variable不应出现在变量名中,Table不应出现在表名中,NameString并不比Name更好,CustomObject也不比Custom更好。
现代编程语言具有丰富的类型系统,编译器也强制使用类型,所以匈牙利语标记法和其他类型编码形式都纯属多余。不必用m_前缀来表明成员变量,应当把类和函数做得足够小,消除对成员前缀的需要。使用某种可以标注成员变量的编辑环境。
其他建议
类名应该是名词或名词短语,函数应该是动词或动词短语。
每个抽象概念(如get、set、controller)对应一个词,并且一直使用它。使用fetch、retrieve、get给不同类的同种方法命名,不如都用get。同一堆代码中有controller、manager、driver就会令人困惑。实际上它们一样,不如全用controller或全用driver。
避免将同一个命名用于不同目的,不同的抽象概念。多个类中有add方法,表示通过增加或连接两个现存值来获得新值,同时某个类的方法要实现把单个参数放到集合中,这个方法就不能叫add,应该用insert或者append。
只有程序员才会读你的代码,所以计算机术语、算法名、模式名、数学术语尽情用。对于熟悉访问者模式的程序员来说,名称AccountVisitor富有含义。