代码规范最佳实践
文/ BlackSwift(简书作者)
原文链接:http://www.jianshu.com/p/8cad7cb9d6ef
代码规范是一个老生常谈的问题,涉及到一个码农的软技能。网上有很多类似的文章,但是有些文章比较落后了,因此需要补充新鲜的文章
主要参考如下
-
《编写可读代码的艺术》
-
《编程的智慧》
-
个人平时积累
我个人对代码规范的要求,主要就是一点:避免自己几个月后看着代码愤而打开提交记录看谁写的渣代码
下面的内容还是比较新的,从逻辑判断、注释规范等方面进行了思考。
1. 代码编写
1.1. 关于if的使用场景
1.1.1. 不要省略if中的其它条件
if是很容易犯错的地方,因此不要省略if中的其它条件,就算它什么也不做也要写出来,否则以后将是一个定时炸弹
if(a < 2){
if(b > 3){
//do sth.
} else{
//do nothing
}
} else{
//do nothing
}
1.1.2. 不要使用反义词
在使用boolean时,不要使用反义词,减少大脑Parser时间
//bad
boolean isNotExistInTable;
if(!isNotExistInTable){
//到底判断条件是啥?负负得正?
}
//good
boolean isEmptyInTable;
if(!isEmptyInTable){
//明白了,这里是Table中元素不为空的场景
}
1.1.3. 法示表达尤用使要不
尤达表示法曾经在C中非常流行,不过它的时代已经过去了
//bad, 多此一举
if(null == str){
}
//good, 因为编译器或者IDE均会进行校验,写成\`str=null\`会被检查出来了
if(str == null){
}
1.1.4. 按照“电路”逻辑进行编写
不要把判断全部写到if括号里
//bad
if(!(age > 18)&&!(today - startday > 30)){
//wtf,大脑分析到一半忘记前面的变量了
}
下面就是按照“电路”逻辑进行编写的,每行一个比较,就算使用了b1
,b2
这样的命名,也能够看得懂。
//good
//必须18以上才能购买
boolean b1 = age > 18;
//如果小于等于30天,那么将没有优惠
boolean b2 = today - startday > 30;
if(!(b1&&b2)){
//
}
1.1.5. 不要使用Lambda表达式
虽然Java8提供了此方法,但是它与JS、Ruby的风格完全不同。在Java中通过接口实现,而在动态语言中通过block或者函数对象实现,信息量也完全不同,除非全部成员都是大神。
不信的话,你写完代码后一个星期后看看是否还看得懂吧。
1.2. 关于流程处理
流程在业务代码中广泛出现,建议除了面试,不要在业务中使用goto、doWhile、contine、break,甚至for/while/iterator代码,它们可以被如下替换
-
try/finally
-
函数式编程: Java8stream, RxJava, Guava, CommonCollection4, 特别推荐stream,它内部与Haskell一样支持惰性求值,效率肯定比自己写的轮子更优秀。
我个人推荐使用函数式表达式,也就是类似于脚本语言的写法来写Java,看黑板:
idea_2016_3_streams_intentions_7.gif
1.3. 注释中加入自己的判断与想法
1.3.1. 使用大家都认可的行话
比如FIXME,TODO等,这个在Intellij中有快捷键
//FIXME: 在某场景下调用时出现一个异常没有复现,详见xxx工单
private doWork(){
}
1.3.2. 警告他人调用的陷阱
//警告,内部使用了for循环查表,可能导致阻塞而变慢
public list<String> querybyId(List<Node> nodes,long id){
}
1.3.3. 注释中描述修改的原因
private doWork(){
//根据工单xxx进行修改,处理了某场景问题
sth.doAnother();
//虽然看似没用,这样写的原因是....
sth2.doAnother();
}
无论何时,只要是你心里所想,只要不是用来粉饰烂代码,就可以写出来,以后代码更新时,可以快速进入状态,避免再次读码而浪费时间
1.3.4. 对重要的对象提供一个例子
在构造变量时,可以通过注释例子帮助理解。不要吝啬代码在VCS中所占用的空间,以免后期查阅文档浪费更多的时间
/**
* the id of employee, \[a-zA-Z0-9/s\]{0,12}
* eg: xyz223344
**/
String id;
/**
* the blur redis, must be power of 2
* eg: 2, 4, 8
**/
int BLUR_RADIS = 8;
/**
* return the person whoes age > ${age}
* eg: (18,\[14,46,18,50\]) -> \[46,50\]
**/
private List<Person> filterByAge(int age, List<Person> person){
}
/**
* valid by regex defined in file: xxx.ccc.bbb.xml
**/
private boolean doVaild(String s){
}
1.4. 使用注解
添加注解,让你的IDE更加智能地进行静态检测
-
Android: Improve Code Inspection with Annotations,注意可以将注解设置为provided模式
-
Java: 使用JavaX自带包,注意这个包里面老是在变,我个人日常也是只用Null判断
1.5. 建立自己的Util
除了Apache等出名的工具类外,也可以将自己的通用代码放入Utils中,好处如下
-
降低代码量
-
对Apache等工具类不完善的地方进行再包装
-
写完了可以骗Star(当然我个人不赞同,也不敢用)
-
熟悉常用的库,减少自己造轮子
2. 编码完成后,使用CodeFormatter
代码格式化(CodeFormatter)工具涉及到审美、对齐、缩进、左括号之争。统一的格式能减少代码阅读时的误判。
我个人推荐用Square的格式,倒入格式后cmd
+alt
+ L
即可
https://github.com/square/java-code-styles
如果你所在公司有自己的格式要求,就算你认为“不合理”,也要按照公司大流来
3. 使用静态分析工具检查源码
静态分析工具通过对Java文件的AST进行分析,找出潜在的问题,通过自动化工具节约时间。
1. Intellij
使用Intellij的代码检查功能,平时尽量处理掉IDE右边的黄色警告(比如未使用的变量、错误的拼写),写完代码后,尽量用Inspect去跑一遍整个代码
2. FindBugs/PMD
这个同上,许多公司都用它作为VCS门禁,没跑通不能上库。在本地环境它可以作为Intellij的插件引入,它是根据class文件进行静态分析的,功能如其名。建议将设置中的报警级别调为最敏感。
4. SUM
总的来说,代码还是需要积累,建议多看源码,不管是我的文章,还是教你写代码的书籍,都不如直接看现成的代码,各位可以mark下面几个项目,纯函数,没有复杂逻辑