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

Java 代碼異味 21 種經典模式識別與重構指南

     編輯:Java 相關知識

Martin Fowler《重構》經典代碼異味目錄的 Java 語境解讀。識別異味是重構的前提,本文對 21 種異味進行分類、成因分析、危害說明、重構手法映射與預防實踐,助力寫出整潔、可維護代碼。

分類總覽

類別異味核心問題
重複與規模1. Duplicated Code邏輯分散、修改遺漏、Copy-Paste 程式設計
2. Long Method單方法承擔過多職責、難理解、難測試、難復用
類級異味3. Large Class類職責過重、違反單一職責原則 (SRP)、實例變數過多
4. Long Parameter List參數過多、調用困難、語義模糊、易傳錯順序
變化與耦合5. Divergent Change單類因不同原因頻繁修改、職責邊界不清
6. Shotgun Surgery單一變更引發多類連鎖修改、關聯邏輯分散
7. Parallel Inheritance Hierarchies平行繼承體系、新增子類必須同步修改多處
8. Inappropriate Intimacy類間過度訪問私有成員、破壞封裝、耦合過緊
特徵依賴9. Feature Envy方法更關心其他類數據、行為歸屬錯位
10. Data Clumps數據項總是成群出現、應提取為獨立對象
11. Primitive Obsession濫用基本類型表達領域概念、缺乏類型安全與行為
結構與邏輯12. Switch Statements基於類型碼/常量分支、違反開閉原則 (OCP)、多態替代
13. Temporary Field字段僅特定情境有效、語義混淆、狀態管理混亂
14. Refused Bequest子類拒絕繼承父類行為、繼承體系設計錯誤
間接與中介15. Message Chains客戶端穿越多層委託獲取對象、脆弱依賴、違反迪米特法則
16. Middle Man類大部分方法僅委託、無實質行為、過度封裝
17. Alternative Classes with Different Interfaces同功能不同介面、缺乏統一抽象、多態受阻
18. Incomplete Library Class庫類缺失所需功能、無法修改源碼、需包裝/擴展
職責缺失19. Data Class純數據容器、無行為、貧血模型、邏輯外泄
20. Lazy Class類職責過輕、維護成本大於價值、應內聯或移除
文檔異味21. Comments過度註釋掩蓋代碼不清、代碼未自說明、重構信號

高頻異味深度解析與重構映射

1. Duplicated Code (重複代碼)

  • 識別:相似代碼塊出現 ≥2 次、相同邏輯不同字面量
  • 重構:Extract Method、Pull Up Method、Form Template Method、Extract Class
  • 原則:OAOO (Once And Only Once) / DRY (Don't Repeat Yourself)

2. Long Method / 3. Large Class

  • 指標:方法 > 30 行 / 類 > 500 行、圈複雜度 > 10、實例變數 > 10
  • 重構:Extract Method/Class、Replace Method with Method Object、Decompose Conditional

5/6. Divergent Change vs Shotgun Surgery

維度Divergent ChangeShotgun Surgery
現象一類因多原因變一變動牽多類
本質類內聚力低模組耦合高
重構Extract Class、Split PhaseMove Method/Field、Inline Class

9. Feature Envy (特徵依賴)

  • 代碼味:`other.getX().getY().calculate()`、大量 Getter 調用
  • 重構:Move Method (移至數據所在類)、Extract Method + Move Method
  • 例外:策略模式、訪問者模式、DTO 組裝器 合理「依賴」

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

  • 反模式:`String phone`、`double money`、`int[] range`、`Map params`
  • 重構:Replace Primitive with Object (Value Object)、Introduce Parameter Object
  • 領域建模:`PhoneNumber`、`Money`、`DateRange`、`Email`、`Id`

12. Switch Statements

  • 重構:Replace Conditional with Polymorphism、Replace Type Code with Subclasses/State/Strategy
  • 現代 Java:Sealed Class + Pattern Matching (JDK 17+) 優雅解決

15. Message Chains (消息鏈)

  • 違反:迪米特法則 (最少知識原則)
  • 重構:Hide Delegate、Extract Method、Introduce Local Extension

19. Data Class (數據類)

  • 特徵:全 Getter/Setter、無業務方法、被動被操作
  • 重構:Encapsulate Field、Move Method、Remove Setting Method (不可變)
  • 區別:DTO/VO 邊界層允許,領域層嚴禁

21. Comments (註釋)

  • 異味註釋:解釋「做什麼」(代碼應自說明)、過時註釋、嘗試補救壞代碼
  • 良性註釋:解釋「為什麼」(業務規則、演算法選擇、非顯而易見決策)、Javadoc 公開 API
  • 重構:Extract Method (註釋變方法名)、Rename Variable、Introduce Assertion

識別工具與實踐流程

靜態分析工具

  • SonarQube / SonarCloud:規則集覆蓋大部分異味、技術債務量化
  • IntelliJ IDEA Inspections:實時檢測、快速修復 (Alt+Enter)
  • SpotBugs / PMD / Checkstyle:CI 管道強制閘門
  • ArchUnit:架構規則驗證 (層級依賴、命名規範、異味模式)

重構節奏

  1. 紅燈停:新代碼提交前跑靜態分析,異味阻斷合併
  2. 綠燈行:重構有測試保護 (單元/整合測試覆蓋核心邏輯)
  3. 小步走:單一重構手法、單一提交、持續集成驗證
  4. 持續改進:定期技術債務專項、Boy Scout Rule (留下比到達時更乾淨)

預防異味的設計原則

原則對應異味核心思想
SRP (單一職責)Large Class, Divergent Change一個類只有一個變化理由
OCP (開閉原則)Switch Statements, Shotgun Surgery對擴展開放、對修改關閉
LSP (里氏替換)Refused Bequest, Parallel Hierarchies子類型可替換父類型
ISP (介面隔離)Alternative Interfaces, Data Clumps介面越小越好、客戶不依賴不需介面
DIP (依賴倒置)Feature Envy, Inappropriate Intimacy依賴抽象而非具體
LoD (迪米特法則)Message Chains, Middle Man只與直接朋友交談
Tell, Don't AskFeature Envy, Data Class告知行為而非詢問數據

總結

代碼異味不是 Bug,而是設計腐化的早期預警信號。掌握 21 種異味識別與重構映射,配合靜態分析工具鏈、測試保護網、SOLID 原則內化,可將重構從「大手術」轉化為「日常保養」。記住:重構的目標不是消除所有異味,而是將代碼保持在可控的技術債務水位,支撐業務快速、安全交付。

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