本文轉載自:http://www.cnblogs.com/mywolrd/archive/2012/04/24/2467395.html
代碼壞味道:是指在代碼之中潛在問題的警示信號。並非所有的壞味道所指示的確實是問題,但是對於大多數壞味道,均很有必要加以查看,並作出相應的修改。
1. 重複的代碼
如果你在一個以上的地點看到相同的程序結構,那麼當可肯定:設法將它們合而爲一,程序會變得更好。
- 同一個class內的兩個函數中含有重複的代碼段
- 兩個兄弟class的成員函數中含有重複的代碼段
- 兩個毫不相關的class內出現重複的代碼段
注意:重複的代碼是多數潛在BUG的溫牀!
2. 過長的函數
擁有短函數的對象會活的比較好、比較長。
- 程序愈長就愈難理解
- 函數過長閱讀起來也不方便
- 小函數的價值:解釋能力、共享能力、選擇能力
原則:每當感覺需要以註釋來說明點什麼的時候,我們就把需要說明的東西寫進一個獨立的函數中。記着,起個好名字!
3. 過大類
如果想利用單一類做太多事情,其內往往就會出現太多的成員變量。
- 提取完成同一任務的相關變量到一個新的類
- 幹太多事情的類,可以考慮把責任委託給其他類
注意:一個類如果擁有太多的代碼,也是代碼重複、混亂、死亡的絕佳滋生地點。
4. 過長的參數列表
太長的參數列表難以理解,太多參數會造成前後不一致、不易使用,而且你需要更多數據時,就不得不修改它。
原則:參數不超過3個!
5. 發散式變化
我們希望軟件能夠更容易被修改。一旦需要修改,我們希望能夠跳到系統的某一點,只在該處做修改。如果不能做到這點,你就嗅出“壞味道:發散式變化”或“壞味道:霰彈式修改”。
發散式變化:一個類受多種變化的影響
- 數據庫新加一個字段,同時修改三個函數:Load、Insert、Update
- 新加一個角色二進制,同時修改四處
- …
原則:針對某一外界變化的所有相應修改,都只應該發生在單一類中
6. 霰彈式修改
如果每遇到某種變化,你都必須在許多不同的類內做出許多小修改以響應之。如果需要修改的代碼散佈四處,你不但難以找到它們,也很容易忘記某個重要的修改。
霰彈式修改:一種變化引起多個類相應的修改
7. 依戀情節
函數對某個類的興趣高過對自己所處類的興趣,就會產生對這個類的依戀情節,造成緊耦合。
原則:判斷哪個類擁有最多被此函數使用的數據,然後將這個函數和那些數據擺在一起。
原則:將總是變化的東西放在一塊。
8. 數據泥團
有些數據項,喜歡成羣結隊地待在一塊。那就把它們綁起來放在一個新的類裏面。這樣就可以:
- 縮短參數列表
- 簡化函數調用
9. 基本型別偏執
代碼中有很多基本數據類型的數據。
原則:如果看到一些基本類型數據,嘗試定義一種新的數據類型,符合它當前所代表的對象類型。
10. switch驚悚現身
面向對象程序的一個最明顯特徵就是:少用switch語句。從本質上說,switch語句的問題在於重複。
原則:看到switch你就應該考慮使用多態來替換它。
11. 冗贅類
你所創建的每一個類,都得有人去理解它、維護它,但一個類沒有存在的必要時候,就讓這個類莊嚴撲義吧!
原則:如果一個類的所得不值其身價,它就應該消失。
12. 誇誇其談其未來性
對未來不可預知的變化考慮的過多,造成系統更難理解和維護。如果應對變化的代碼都會被用到,那是值得的那麼做;如果用不到,就不值得。
原則:代碼應該滿足當前的需求,並留有可擴展的餘地。對於未來的變化,既不要考慮的太多,也不能一點都不考慮。
13. 令人迷惑的暫時成員變量
有時你會看到這樣的對象:其內某個成員變量僅爲某種特定的情形而設。這樣的代碼容易讓人不解,因爲你通常認爲對象在所有時候都需要它的所有變量。
在變量未被使用的情況下猜測當初設置目的,會讓你發瘋。
14. 無用的中間人
過度使用委託。你也許會看到某個類的接口有一半的函數都委託給其他類,這樣就過度運用了。所以,刪除無用的中間人。
15. 狎暱關係
有時你會看到兩個類過於親密,花費太多時間去探究彼此的private成分。
原則:過分狎暱的類必須拆散。
16. 異曲同工的類
如果兩個函數做同一件事情,卻有着不同的簽名式。
原則:刪除一個,保留一個。
17. 不完美的程序庫類
庫的設計有時會不夠好,不那麼容易使用,可能還會有那麼一點小缺陷。
工具:
- Introduce Foreign Method
- Introduce Local Extension
18. 過多的註釋
過多註釋的代碼段,往往都是因爲那段代碼比較糟糕,散發着一股惡臭。
原則:當你感覺需要寫註釋時,請嘗試重構,試着讓所有註釋都變得多餘。
參考資料:
- 《重構:改善既有代碼的設計》
- 《重構手冊》