影響代碼可閱讀性的常見問題

含混不清的命名

命名問題是很嚴重的問題,我見過有些系統用大量拼音縮寫命名,有些縮寫長達5-6個字母以上,這種除非是長期維護系統的程序員,其他人看了都是一臉懵逼。

命名最好用英文加上駝峯命名法,比如getAccount,userName。對於英文單詞的選擇,由於我們是非英語國家,即使在英語國家裏面,同一個含義可能也對應多個單詞,最好團隊建立一個常用英文單詞庫,比如性別都叫:gender,而不是有的用sex,可以建立團隊內部Wiki解決。

清晰的命名,應該讓其他人一眼看去就知道這個東西大概是幹什麼的。我很不喜歡的一種命名是類成員都加上m開頭,如mUserName,這個毫無必要。接口前面也不必加上I,另外以下劃線開頭的習慣我更覺得是一種干擾。

過長的函數

一般過長的函數表明這個函數承擔了太多責任,可以用Extract Method將部分責任分給其他更小的函數。責任太多的函數將很難閱讀,閱讀者由於很多計算的干擾而看不清你的主線。一般函數控制在20行以內,10行以內更好。

過大的類

過大的類和過長的函數類似,不過是一個類可能承擔了太多責任。可以把部分責任擴展爲新的類,用委託的方式實現。

濫用的繼承

我曾經碰到有個系統,有多達5-6層的繼承,最底層的實現,又一路用super調用到最上層的類。當你查看某一個功能的代碼時,你不得不打開N個窗口,在不同的類之間跳來跳去。

除了一些特殊情況,如Template模式,要謹慎使用繼承。如果可以使用聚合,就不必去使用繼承。如果僅僅是爲了共享部分代碼而用繼承,這個就完全沒有必要。

魔鬼金字塔

魔鬼金字塔是指多層的向右縮進,就像金字塔一樣。有說法人類的大腦只能暫存3層棧,如果多層嵌套,大腦將很難記住前面的嵌套到哪裏了。解決辦法是將部分代碼Extract method組成新的方法,保持主方法比較乾淨。

Callback hell

這是另外一種反模式,我曾經看到過3-4層甚至以上的Callback嵌套,當時的程序員即使是很有經驗的,也差點崩潰了。Callback在某些情況下是提高了效率,不過不可濫用,一般來說我覺得一層就足夠了。

設計模式濫用

設計模式是好東西,在某些環境下,設計模式爲了解決某些特定問題是非常好的。設計模式的基礎是面向抽象編程,只要你遵循面向抽象編程,就不必非要到處硬套設計模式。一個系統裏面有幾個地方使用設計模式挺好,如果到處都是設計模式,你就要崩潰了。

過多的配置

有些系統外面用了太多文件對系統進行配置,以至於光看代碼,你根本不知道他們怎麼組合在一起的(這也是我不太喜歡早期Spring用XML進行裝配的原因)。Java有了Annotation後,把代碼和配置寫在一起,一定程度上解決了這個問題。

濫用註釋

註釋是好東西嗎?可能有些地方是。但最好的註釋我認爲是對函數、變量、成員、類的良好命名,讓人僅僅看名字就能理解代碼而不是靠註釋。如果代碼中有過多註釋,還影響代碼的閱讀。我看到有些開源庫,註釋多到你找不到代碼在哪裏!

註釋還有個最大的問題是和代碼的同步性,有些代碼改了,註釋卻未必同步了。這樣註釋編程沒用的甚至是錯誤的,這帶來更大問題。

函數過多參數

函數參數如果過多(超過3個),在調用的地方就很難弄清楚順序,爲了弄清楚就不得不跑到聲明的地方看一看,這時候可以用個類把這些參數聚合起來。

現在有些IDE如intelij idea的最新版本,可以在調用的地方標出參數名稱,這個很有幫助,不過還是儘量不要太多爲好。

反覆修改的臨時變量

在函數中聲明一個臨時變量,最好聲明爲final的(除了一些循環因子如i),在第一次賦值即不允許改變。一個允許變來變去的臨時變量,將給閱讀帶來很多困擾。

在函數中修改入參

調用一個函數,如果會對入參帶來副作用,比如對傳入的一個List進行操作,對調用方將比較困擾。如果你確實需要,寧可返回一個新的List。幸好Java中只允許值傳遞,你對入參賦值不影響調用方,否則更麻煩。

一個函數多個責任

我曾經遇到一個Bug,一個人有多個名字:暱稱、別人給你的別名、通信錄中的名字,不同的地方顯示的名字不同。然後開發人員把這些setter方法,裏面又加了代碼對對象進行操作,導致最後完全搞不清誰會修改代碼。解決辦法是把setter都恢復乾淨,然後另外寫了一個讀取showName的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章