5.2 避免在名字中拼错单词
Case1:接口拼错单词,实现类也被迫保持队形
代码示例:
public interface xxx { .... void destory(); }
修改建议:
public interface xxx { .... void destroy(); }
6、类的命名
应该总是名词在最后面,名词决定了这个类代表什么,前面的部分都是用于修饰这个名词;比如,假如现在你有一个服务,然后又是一 个关于订单的服务,那就可以命名为OrderService,这样命名就是告诉我们这是一个服务,然后是一个订单服务;再比如 CancelOrderCommand,看到这个我们就知道这是一个Command,即命令,然后是什么命令呢?就是一个取消订单的命令,CancelOrder表示取消订单。
类的命名可以参考前面讲述过的规则。实际上往往了解一个类更多需要通过查看类的方法定义,而仅仅通过类名无法知晓类是如何工作的。关于类的更多内容,会在后续章节详细展开。
7、方法的命名
可以用一个较强的动词带目标的形式。一个方法往往是对某一目标进行操作,名字应该反映出这个操作过程是干什么的,而对某一目标进行操作则意味着我们应该使用动宾词组。比如:addOrder()。当方法有返回值的时候,方法应该用它所返回的值命名,比如currentPenColor()。
《代码大全》:变量名称的最佳长度是 9 到 15 个字母,方法往往比变量要复杂,因而其名字也要长些。有学者认为恰当的长度是 20 到 35 个字母。但是,一般来说 15 到 20 个字母可能更现实一些,不过有些名称可能有时要比它长。
7.1 避免对方法使用无意义或者模棱两可的动词
避免无意义或者模棱两可的动词 。有些动词很灵活,可以有任何意义,比如 HandleCalculation(),processInput()等方法并没有告诉你它是作什么的。这些名字最多告诉你,它们正在进行一些与计算或输入等有关的处理。
所用的动词意义模糊是由于方法本身要做的工作太模糊。方法存在着功能不清的缺陷,其名字模糊只不过是个标志而已。如果是这种情况,最好的解决办法是重新构造这个方法,弄清它们的功能,从而使它们有一个清楚的、精确描述其功能的名字。
Case1: 名不副实的process
代码示例:
/** * 处理主图的数据 * * @return 如果有浮层数据就返回true,没有就返回false */ private boolean processMainPic() { .... boolean hasMainPicFloat = false; .... return hasMainPicFloat; } // 调用处 boolean hasMainPicFloat = processMainPic();
大脑活动:
1、方法名的字面意思是处理主图(暂不纠结缩写Pic了),但是是如何处理主图的呢?
2、返回值是bool类型,是表示处理成功或失败吗?
3、查看注释解释,当前方法是在处理主图的数据,返回为是否存在浮层数据,为什么一个处理主图数据的方法检查的是浮层数据呢?
看完发现,这个方法原来是拿主图数据检查其中是否存在浮层数据,名不副实呀。
修改建议:
额外说明:既然工程默认“Float”是浮层,这里不做额外修改,但实际上不合理,毕竟Float在Java中表示浮点型数据类型,会引起误解。
/** * 是否有浮层数据 * * @return 如果有浮层数据就返回true,没有就返回false */ private boolean hasFloatData($MainPictureData) { .... boolean hasFloatData = false; .... return hasFloatData; } // 调用处 boolean hasFloatData = hasFloatData(mainPictureData);
Case2: 我该如何正确使用这个方法
代码示例:
// 10多处调用 ... = GatewayUtils.processTime(System.currentTimeMillis()); public class GatewayUtils { .... // 这个方法没有注释 public static long processTime(long time) { return time + (SDKUtils.getTimeOffset() * 1000L); } .... }
大脑活动:
好多地方调用工具类的processTime,processTime到底是在处理些什么呢?
如果入参传入的不是 System.currentTimeMillis() 而是 SystemClock.uptimeMillis() 或者随意传入一个long值,方法的返回值会是什么呢?
修改建议:
public static long currentNetworkTime() { return System.currentTimeMillis() + (SDKUtils.getTimeOffset() * 1000L); }
7.2 避免返回和方法名定义不一致的类型
Case1: 私有方法就可以乱定义吗?
码示例:
// 唯一调用处 final IPageProvider pageProvider = checkActivityAvaliable(); if (pageProvider == null) { .... return; } // 函数声明 private IPageProvider checkActivityAvaliable() { IPageProvider pageProvider = pageProviderWeakReference.get(); if (pageProvider == null) { PopFactory.destroyPopCenter(pageName); return null; } return pageProvider; }
大脑活动:
check方法如果有返回值的话不应该是bool类型吗?
“Avaliable”拼错了诶,正确的单词拼写是:“Available”。
“IPageProvider” 和 “ActivityAvaliable” 是什么关系,为什么校验可用的Activity返回的是“IPageProvider”。
代码跟读:
原来方法里面偷偷做了一个销毁“PopCenter”的动作。把获取“PageProvider”和销毁“PopCenter”两件事情放在了一起。确实没看懂方法名和方法所做任何一件事情有什么关系。
修改建议:
干掉checkActivityAvaliable()方法。(这里不展开讨论高质量的函数相关内容)
final IPageProvider pageProvider = pageProviderWeakReference.get(); if (pageProvider == null) { PopFactory.destroyPopCenter(pageName); .... return; }
四、养成良好的命名习惯一些建议
1.对自己严格自律,自己写代码时要有一种希望把每个名称都命名好的强烈意识和严格的自律意识;
2.要努力分析和思考当前被你命名的事物或逻辑的本质;这点非常关键,思考不深入,就会导致最后对这个事物的命名错误,因为你还没想清楚被你命名的事物是个什么东西;
3.你的任何一个属性的名字都要和其实际所代表的含义一致;你的任何一个方法所做的事情都要和该方法的名字的含义一致;
4.要让你的程序的每个相似的地方的命名风格总是一致的。不要一会儿大写,一会儿小写;一会儿全称一会儿简写;一会儿帕斯卡(Pascal)命名法,一会儿骆驼(Camel)命名法或匈牙利命名法。