90%的程序員都犯過的代碼錯誤

 

最近參加了屢次的代碼review會,在review的過程當中,發現有些問題幾乎每次都出現。挑了幾個比較典型的問題講解下。這幾個問題都是初級問題,解決方法都很容易。只要掌握了方法,有意識避免,能讓短期內迅速提升代碼質量。真所謂投入小,見效快。chrome

變量命名不清晰,一詞多義

爲變量命名時最重要的考慮事項是,該名字要徹底、準確地描述出該變量所表明的事務。容易閱讀,不會與其餘事務混淆。瀏覽器

例如:markdown

if(staff_id == 0)
{
    printf("系統歸檔,不是員工歸檔");
}

上面這段代碼,staff_id是員工號的意思,用staff_id爲0表示是系統歸檔。一詞多義,原本應該把系統和人分開,可是混用到了一個變量。若是調用方出現個bug忘記把初始化的變量賦值,還會走到意外的邏輯。app

解決方法是變量名稱首先要符合變量的實際意義,沒有歧義;對於一個變量名,不用特定值表示特殊邏輯函數

有些代碼會把變量取不到的值賦予其餘的意義,感受是省事了,實際後患無窮。例如用戶名不可能爲空,就用空值表示這個用戶數據已經被刪除了。並且斷定數據是否刪除的代碼看着也讓人莫名其妙。測試

總之,變量命名要保證沒有「潛規則」,防止給本身挖坑。優化

使用魔數

命名不清晰更嚴重的是,沒有命名,直接用魔數。若是連註釋都沒有,就只能靠猜。ui

使用魔數有兩個很差的地方:url

一、不方便修改。spa

使用常量替換魔數是一種將程序「參數化」的方法,須要修改改動一處就能夠了,而沒必要代碼中處處修改。
例如在代碼中默認綁定的端口是80,若是不用一個常量代替,哪天軟件升級默認端口變成443了。要整個代碼搜索80這個數字,既耗時,又容易改錯。

二、代碼不方便閱讀。

只有一個數字,很難了解到具體的意思。

for(int i = 0; i < 13; ++i)
{
    ...
}

上面這段代碼,只看13,誰能猜出來是什麼意思呢,爲何用13這個數值?可能只有寫代碼的人和上帝知道,若是天長日久,寫代碼的人忘記了,就只有上帝知道了。

也有同窗會問,有的數字只用到一個地方,也起個常量的名字會不會太麻煩了?

答案是:不麻煩。給魔數起個好名字是應該的,這是對的事,不要由於麻煩就不作。有時爲了起個準確的名字,甚至要查下詞典。

有一個經常使用的斷定方式:

1、若是引用魔數的地方不超過3個,直接用數字影響也不大。若是超過了3個,都是表示同一個數值意義,仍是乖乖地用有意義的變量名代替。

2、若是魔數自己就是表示一個純粹的數字定義,例如是幾米、幾千克這種,做爲參數傳遞。在函數的定義明確表示了形參數所表明的意義。你們看用到的地方和函數定義,就知道數字是表示多少個單位的意思,能夠用魔數。可是若是用數字表示種類,例如

const int ieBrowser=1;
const int chromeBrowser=2;

表示瀏覽器的種類,若是直接只是看到1或2,是不明白什麼意思的。即便在函數聲明的地方已經說過是瀏覽器種類了,也不要用魔數。

魔數解決的辦法很簡單:用枚舉、常量等方式,代替魔數

if else 或switch等邏輯判斷語句太長

例以下面的僞代碼代碼,條件分支不少,用很長的if else語句或者switch語句才能表達完整的邏輯,要思考下是否能用「表驅動」方式來優化。

const int CN=1;
const int US=2;
const int UK=3;

string language;
if(country==CN)
{
    language="中文";
}
else if(country==US)
{
    language="english";
}
else if(country==UK)
{
    language="english";
}
else
{
    language="";
}

條件分支太多太長有幾點很差:

一、代碼太長,不易閱讀。

若是超過了一個屏幕能表示的長度,要翻頁才能看完代碼,會大大下降看代碼的效率。由於代碼的信息密度過低了。

二、不易擴展,修改代碼。

就像上面的例子,若是又增長了新的條件判斷,那麼要增長新的if else語句,因爲修改了邏輯,要從新測試,也要防止改錯。

能夠用「表驅動」的方式替代太長的邏輯分支

把每一個條件要用到的數據放到一個「表」裏。用條件分支的判斷條件來索引到表中的數據。
上面的代碼能夠修改成

const int CN=1;
const int US=2;
const int UK=3;

string languageTable[]={"","中文","English","English"};
//先判斷country變量是否在定義的CN、US、UK範圍內,若是在繼續
language = languageTable[country];

通過修改,代碼變得很短,一眼就能看出代碼所表示的邏輯。並且之後更新的只有數據,邏輯部分不用修改。

使用「表驅動」後,邏輯和數據分離。使得新增數據修改簡單,並且一目瞭然。

總結

上面只是簡單的說明了幾種常見的代碼書寫錯誤。稍加註意,就可以在短期內迅速提高代碼質量。具體的方法能夠參考一些代碼規範,或者重構的書籍,例如「表驅動」會有更詳盡的介紹。

最本質的仍是要從意識上有足夠的認識。代碼是寫給人看的,寫代碼時要有同理心,想到之後讓閱讀代碼的人儘可能可以不費力讀懂。換位思考,若是你就是review人,或後面接手這個代碼的人,你會喜歡這段代碼嗎?

畢竟代碼閱讀的次數遠遠超過編寫的次數。確保代碼閱讀方便,而不只是編寫方便

相關文章
相關標籤/搜索