一、从命名做起
1.1类的命名
在java中,一个类的名字,不仅能让人一眼看出来这是什么,最好还是得让人看出来它是用来做什么的,就像美团外卖员的帽子是黄色的,而饿了么外卖员的帽子是蓝色的一样,你能够一眼就能够区分。比如,你要写一个Controller,那么你就不该命名为MailFilter,因为别人会以为你这玩意是一个过滤器,至少我会这么认为。以下是我个人矢志不渝坚持的原则:
- 类的首字母务必大写,这一点,没得商量。
- 类的名字,前面的部分要突出它是干什么的,而结尾的部分要表明它是什么。诚如开头所言,如果你想定义一个邮箱相关功能的控制器,那么MailController目前来看是合理的。但是如果邮箱相关的功能会更加细分的话,这个名称又显得比较抽象了。
- 如果你接手一个项目,发现其它成员不遵守如上约定,就算你没空也不愿意去修改它们,自己也不能随波逐流。
1.2变量的命名
垃圾的变量命名会使得代码的可读性大大降低,会让维护人员破口大骂,这个维护人员说不定就是当时的开发人员。我个人认为的原则如下:
- 从原则上讲,变量的命名方式跟类几乎一样,唯一的不同之处在于:变量的名称首字母必须小写。 如果你定义的是一个map,且是用来做封装返回结果参数的,那么你就可以命名为resultMap。
- 坚决杜绝单个字符的变量名,比如i,m,n等,尤其是l和o。因为你不知道它到底是l和o,还是1和0。我曾经的一个项目组组长告诉我,因为某一位开发成员命名为l的缘故,导致整个项目组排查这个问题花了一整天时间。对了,不仅成员变量不要那么命名,for循环的局部临时变量也最好不要那么命名。这种一般不会出现问题,但是出现循环嵌套的时候,就很容易出问题了。这一点,写过代码的人应该深有体会。
- FINAL修饰的不可修改的全局变量,命名方式则是一个例外,它一般全部为大写字母,且字母之间用下划线相连,如:USER_PASSWORD。这样才能体现出它们的特殊性。
- 杜绝魔法值。什么叫魔法值?打个比方,请看下面的代码,代码中,3就是一个魔法值。为什么呢?因为你不知道3从业务角度具体代表什么含义。也许你会在旁边写一个注释:3表示这是一个正方体,但是一旦这个注释被删除,一切又将从零开始。更可怕的是,你找不到最初的开发人员了………………那么我们应该怎么写呢?如下,在类的一开始先给它定义一个名字,若种类较多,可以定义一个枚举类。
//错误范例
if(paramType == 3){
//执行具体的逻辑操作
}
//正确范例
public final Integer CUBE_TYPE = 3;
if(paramType == CUBE_TYPE){
//执行具体的逻辑操作
}
- 杜绝value1、value2这样的命名方式,求求你了。
- 废话都是冗余。variable一词永远不要出现在变量名中,就像table永远不要出现在数据库的表名中一样。这是《代码整洁之道》中的原话。 截图为证:
二、怎么样写函数才够简洁?
函数是编写java代码中,不可或缺的一个东西。所有依赖引入的lib包,从本质上讲,就是方便你调用的一系列的函数。它们像工具箱一样,解决了你各种各样的需求,比如:数据库连接、密码加密、发送http请求等等。 但是,当你自己亲自写一个静态函数或者类的公共或者私有方法的时候,你能够尽可能得让它变得简洁吗?其中有什么原则呢?
2.1 取个好名字
跟类和变量一样,函数也需要一个好名字,它的原则是“动宾结合”!比如,我是一个发邮件的函数,那么命名为sendMail;比如,我是一个校验密码的函数,那么命名为checkPassword。如此一来,任何人阅读你这段代码的时候,尽管不去看详细内容,也知道你这段代码想干啥。
2.2 尽量减少输入参数
请看下面这个方法:
public WapiResponse validator(Map<String, Object> requestbody, HttpServletRequest request, String id, String userId, String unitParam, String processParam, String objType) throws ServiceException {
上面代码存在两个问题:第一,参数名不明确,id是什么id?objType又是表示什么类型呢?第二,就是参数过多,如果我想调用这个方法,那么我要依次输入参数,且不能搞错顺序,倒不是说这种写法存在什么bug,而是不利于开发人员开发。
2.3 一个函数只干一件事儿
用专业名词来说就是单一职责原则。比如下面这段代码:(偷个懒,下面这段代码也是从《代码整洁之道》中摘抄而来)
我们能看到,这里面有一个校验密码的方法。但是这个方法里面,藏了一个会话实例化的方法,即我红色框出的位置。这就表明,我校验密码成功的时候,默认是要实例化会话的。如果其它地方只是想单纯的校验密码怎么办?如果发现还好,大不了重写一个方法,但是没有发现就存在一个隐患了。正确的解决方法,要么把这个会话实例化方法拿出来,要么修改方法名为checkPasswordAndInitialSession().