引子
我前幾天看了一本書,書中有這麼一句話:“複雜的代碼往往都是新手所寫,只有經驗老道的高手才能寫出簡單,富有表現力的代碼”此話雖然說的有點誇張,可是也說明了經驗和智慧的的重要性。我們所寫的代碼主要是爲了閱讀,其次纔是被機器執行。所以我們要寫:是給人讀的代碼,而不是給機器讀的。
我經歷過的公司還沒遇到有一個統一可複用的規範的,也經常遇到上級領導要求推行一套規範,一般是一個從網上直接拷貝下來的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;
}