首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 開發中 21 種常見代碼壞味道與重構對策

     編輯:Java 相關知識

前言

Martin Fowler 《重構》一書系統梳理了代碼壞味道。本文針對 Java 語言特性,精選 21 種高頻問題,說明成因、危害及重構方向,助力編寫整潔、可維護代碼。

壞味道清單與對策

  1. Duplicated Code(重複代碼)

    成因:Copy-Paste 編程。
    對策:Extract Method、Pull Up Method、Extract Class。遵循 OAOO(Once And Only Once)原則。

  2. Long Method(過長方法)

    成因:結構化編程遺毒,多意圖混雜。
    對策:Extract Method,單一職責,方法 5-15 行為宜。

  3. Large Class(過大類)

    成因:承擔過多職責。
    對策:Extract Class/Subclass/Interface,遵循「一個類一個職責」。

  4. Divergent Change(發散式變化)

    成因:類內因不同原因頻繁變更(如業務邏輯變、DB Schema 變)。
    對策:Split Phase、Extract Class,隔離變化維度。

  5. Shotgun Surgery(霰彈式修改)

    成因:單一變更需修改多個類(如新增字段涉及 Entity、DAO、Service、Controller、DTO)。
    對策:Move Method/Field,將相關變化聚合到同一模組。

  6. Feature Envy(特性依戀)

    成因:方法頻繁訪問其他類數據(getter 狂呼)。
    對策:Move Method 到數據所在類,或引入 Rich Domain Model。

  7. Data Clumps(數據泥團)

    成因:多個數據總同時出現(參數列、字段組)。
    對策:Extract Class 封裝為值對象(如 Address, Money, DateRange)。

  8. Primitive Obsession(基本類型偏執)

    成因:用 int/String/double 表達領域概念(金額、郵編、電話)。
    對策:引入值對象(Money, Email, PostalCode),利用類型系統約束邏輯。

  9. Switch Statements(開關語句)

    成因:基於常量/枚舉的 switch/if-else 鏈。
    對策:Replace Conditional with Polymorphism(Strategy/State 模式),或 Map/函數式分派。

  10. Parallel Inheritance Hierarchies(平行繼承體系)

    成因:新增一子類必須同步新增另一體系子類。
    對策:Move Method/Field 合併體系,或用組合替代繼承。

  11. Lazy Class(冗餘類)

    成因:類幾乎無行為/狀態,維護成本 > 價值。
    對策:Inline Class,折疊到調用者。

  12. Speculative Generality(投機性通用性)

    成因:為「未來可能」實現未用功能,唯一用戶是測試。
    對策:YAGNI 原則,刪除無用代碼,需要時再加。

  13. Temporary Field(臨時字段)

    成因:字段僅在特定場景有效(如演算法中間變量)。
    對策:Extract Class 封裝臨時狀態與行為,或改為方法局部變量。

  14. Message Chains(消息鏈)

    成因:a.getB().getC().doSomething() 客戶端依賴完整對象圖結構。
    對策:Hide Delegate,在中間類添加委派方法,或引入 Facade。

  15. Middle Man(中間人)

    成因:類過度委派,接口大多數方法僅轉發。
    對策:Remove Middle Man,讓客戶直接訪問真實對象。

  16. Inappropriate Intimacy(過度親密)

    成因:兩類互相探訪私有成員(反射、友元、同包訪問)。
    對策:Move Method/Field、Extract Class、Change Bidirectional Association to Unidirectional。

  17. Alternative Classes with Different Interfaces(異名同構)

    成因:功能相似類擁有不同方法簽名。
    對策:Rename Method、Move Method 統一協議,提取共同介面。

  18. Incomplete Library Class(不完美庫類)

    成因:第三方庫缺所需方法,難以修改源碼。
    對策:Introduce Foreign Method(工具類)、Introduce Local Extension(子類/包裝類/適配器)。

  19. Data Class(純數據類)

    成因:類僅有字段 + getter/setter,無行為。
    對策:Encapsulate Field、Move Method 將行為遷入,或轉為 Record (JDK14+)/Value Object。

  20. Refused Bequest(拒絕遺贈)

    成因:子類僅使用父類極小部分功能,繼承體系設計錯誤。
    對策:Replace Inheritance with Delegation,或 Push Down Method/Field。

  21. Comments(過度註釋)

    成因:代碼不夠自解釋,需大量註釋補充。
    對策:Rename/Extract Method 讓代碼成爲最好文檔,保留「為什麼」註釋而非「做什麼」。

重構原則速查

  • 小步快跑:每次重構單一目標,持續運行測試。
  • 紅-綠-重構:TDD 循環中重構最安全。
  • 工具輔助:IntelliJ IDEA/Eclipse 內建重構菜單(Extract, Move, Rename, Inline, Pull Up/Push Down)。
  • 代碼審查:將壞味道識別納入 Code Review 清單。

壞味道非絕對錯誤,而是「值得關注的信號」。熟練識別並果斷重構,是從「能跑通」邁向「好維護」的關鍵飛躍。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved