引子
我前几天看了一本书,书中有这么一句话:“复杂的代码往往都是新手所写,只有经验老道的高手才能写出简单,富有表现力的代码”此话虽然说的有点夸张,可是也说明了经验和智慧的的重要性。我们所写的代码主要是为了阅读,其次才是被机器执行。所以我们要写:是给人读的代码,而不是给机器读的。
我经历过的公司还没遇到有一个统一可复用的规范的,也经常遇到上级领导要求推行一套规范,一般是一个从网上直接拷贝下来的Word文档,通篇读下来就需要几个小时,所以往往起不到什么好的执行效果,讲得太多起不到好的执行效果反而不好。
概论
找出一套简单可行的,能有效增加代码可读性和可维护信的东西,我能想到的包括以下几点:
- 减少重复代码;一般来说代码越少,出现Bug的机率越小
- 简洁;
- 有表达力
- 只做一件事
具体分析
过多的注释反而影响阅读。
如果你正在考虑使用注释,代码本身很可能存在表达问题了,因为需要阅读注释才知道Coder需要表达的含义。而且常常存在这种情况:代码后面修改,但是代码注释往往不会修改,很容易造成再后面的阅读者看得更加懵懂。
/**
* 获取消费总金额
*/
public int getCash() {
// 购买消费数据量
int[] array = { 1, 2, 3 };
// 单价
int a = 20;
// 消费金额总和
int b = 0;
// 遍历
for (int temp : array) {
b += temp * a;
}
return b;
}
重构后:
public int getTotalCash() {
int[] cashCounts = { 1, 2, 3 };
int price = 20;
int total = 0;
for (int cashCount : cashCounts) {
total += cashCount * price;
}
return total;
}
使用过多的参数
public class MoreParams {
public void registerUser(String name, String tel, String password,
String info) {
// TODO register
}
重构后
public void registerUser(User user) {
// TODO register
}
}
不要用if/else给布尔变量赋值
反例
public boolean isAdult(int age) {
boolean isAdult;
if (age > 18) {
isAdult = true;
} else {
isAdult = false;
}
return isAdult;
}
重构
public boolean isAdult(int age) {
boolean isAdult = age > 18;
return isAdult;
}
不要使用过多嵌套判断,使用前置条件
反例
if (user != null) {
if (user.name != null) {
if (user.password != null) {
// do something
}
}
}
重构
if(user==null) return false;
if(user.name==null) return false;
if(user.password==null) return false;
//do something
不要使用魔数、HardCode
反例
if (user.age > 18 && user.carName.equals("BMW")) {
}
重构
public final static int ADULT_AGE = 18;
if (user.age > ADULT_AGE && user.carName.equals(Car.BMW)) {
}
不使用双重否定判断
反例
if (!isNotRemeberMe)
{
}
重构
if (isRemeberMe)
{
}
不要在判断语句中加入太多条件
反例
if (job.JobState == JobState.New
|| job.JobState == JobState.Submitted
|| job.JobState == JobState.Expired
|| job.JobTitle.IsNullOrWhiteSpace())
{
//....
}
重构后
if (CanBeDeleted(job))
{
//
}
private bool CanBeDeleted(Job job)
{
var invalidJobState = job.JobState == JobState.New
|| job.JobState == JobState.Submitted
|| job.JobState == JobState.Expired;
var invalidJob = string.IsNullOrEmpty(job.JobTitle);
return invalidJobState || invalidJob;
}