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

Java 23 種設計模式全解析:創建型、結構型、行為型模式實戰指南與六大原則

     編輯:Java 相關知識

設計模式分類總覽

類別模式 (共 23 種)核心意圖
創建型 (5)工廠方法定義創建介面,子類決定實例化哪個類
抽象工廠創建相關/依賴物件家族,無需指定具體類
單例確保類僅一實例,提供全域存取點
建造者分步驟構建複雜物件,分離構建與表示
原型複製現有實例創建新物件,避免繁瑣初始化
結構型 (7)適配器將介面轉換為客戶期望的另一介面
裝飾器動態給物件添加職責,靈活替代繼承
代理為其他物件提供代理,控制存取
外觀提供統一高層介面,降低子系統耦合
橋接抽象與實現分離,兩者可獨立變化
組合樹形結構統一單一/組合物件操作
享元共享細粒度物件,減少記憶體開銷
行為型 (11)策略定義算法族,封裝互換,客戶端選擇
模板方法定義算法骨架,延遲步驟到子類
觀察者一對多依賴,狀態變更自動通知
迭代器順序存取聚合元素,不暴露內部結構
責任鏈請求沿鏈傳遞,自動尋找處理者
命令將請求封裝為物件,支援撤銷/佇列
備忘錄捕獲物件內部狀態,支援恢復
狀態狀態變更改變行為,物件似修改類別
訪問者分離數據結構與操作,易添加新操作
中介者封裝物件互動,降低多對多耦合
解釋器定義語言文法與解釋器

六大設計原則 (SOLID + 更多)

  1. 開閉原則 (OCP):對擴充開放、對修改關閉 — 介面/抽象類固定,新增實作不動舊碼
  2. 里氏替換 (LSP):子類必須能替換父類不破壞功能 — 繼承即契約
  3. 依賴倒置 (DIP):依賴抽象不依賴具體 — 高層模組不依賴低層,皆依賴抽象
  4. 介面隔離 (ISP):多個專用介面優於單一臃腫介面 — 降低耦合
  5. 迪米特法則 (LoD):最少知識 — 僅與直接朋友溝通,減少關聯
  6. 合成復用 (CRP):組合/聚合優於繼承 — 靈活、低耦合

精選模式深度解析與代碼範例

1. 單例模式:線程安全的演進

// 最終推薦:靜態內部類 (延遲載入 + 線程安全 + 簡潔)
public class Singleton {
    private Singleton() {}
    private static class Holder { static final Singleton INSTANCE = new Singleton(); }
    public static Singleton getInstance() { return Holder.INSTANCE; }
}

關鍵點:JVM 類載入機制保證線程安全、final 保證不可變、首次呼叫才初始化。

2. 工廠方法 vs 抽象工廠

  • 工廠方法:單一產品等級結構,一個工廠對應一個產品 (如 SenderFactory.produceMail())
  • 抽象工廠:多產品族,工廠介面定義多個創建方法 (如 Provider.produce() + 多個具體工廠)

3. 適配器模式三種變體

  • 類適配器:繼承 Adaptee + 實作 Target (單繼承限制)
  • 物件適配器:組合 Adaptee 實例 + 實作 Target (推薦,靈活)
  • 介面適配器:抽象類實作介面所有空方法,子類僅覆寫所需 (如 Spring HandlerInterceptorAdapter)

4. 裝飾器 vs 代理

維度裝飾器代理
意圖**增強**功能 (添加行為)**控制**存取 (延遲/保護/遠程)
關係持有被裝飾者引用,介面相同持有真實主體引用,介面相同
建立客戶端層層包裝通常由框架/工廠建立

5. 觀察者模式現代實現

Java 內建 Observable/Observer 已棄用。推薦:

  • Spring ApplicationEventPublisher + @EventListener
  • RxJava Observable/Flowable (背壓、操作子豐富)
  • Guava EventBus (輕量進程內)

6. 策略模式消除 if-else

// 介面定義算法
interface Calculator { int calc(int a, int b); }

// 具體策略
class Add implements Calculator { public int calc(int a, int b) { return a + b; } }
class Multiply implements Calculator { public int calc(int a, int b) { return a * b; } }

// Context 使用
class Context {
    private Calculator strategy;
    public Context(Calculator strategy) { this.strategy = strategy; }
    public int execute(int a, int b) { return strategy.calc(a, b); }
}

7. 模板方法固定流程

abstract class AbstractCalculator {
    // 模板方法 final 防止覆寫
    public final int calculate(String exp, String opt) {
        int[] nums = split(exp, opt);
        return doCalculate(nums[0], nums[1]); // 延遲到子類
    }
    protected abstract int doCalculate(int a, int b);
    private int[] split(String exp, String opt) { /* ... */ }
}

模式選擇決策指南

  1. **創建物件複雜** → 建造者/工廠/原型
  2. **介面不兼容** → 適配器
  3. **動態添加功能** → 裝飾器
  4. **控制存取/延遲載入** → 代理
  5. **簡化子系統介面** → 外觀
  6. **抽象與實現獨立變化** → 橋接
  7. **樹形結構統一操作** → 組合
  8. **大量相似物件共享** → 享元
  9. **算法可互換** → 策略
  10. **流程固定步驟可變** → 模板方法
  11. **狀態變更行為改變** → 狀態/觀察者
  12. **請求多處理者可選** → 責任鏈/命令
  13. **需撤銷/記錄/佇列請求** → 命令
  14. **需保存/恢復狀態** → 備忘錄
  15. **數據結構穩定操作易變** → 訪問者
  16. **多對多互動解耦** → 中介者
  17. **語言/規則解析** → 解釋器

實務建議

  • **模式非銀彈**:理解意圖、權衡複雜度,不要為用模式而用模式
  • **重構導向模式**:先寫簡單代碼,演進中引入模式 (如策略替換 if-else)
  • **組合優於繼承**:策略/裝飾/代理皆用組合實現開閉原則
  • **命名揭示意圖**:類名包含模式名 (UserBuilder, OrderProxy) 利團隊溝通
  • **現代語言特性簡化模式**:Lambda 替代策略/命令/觀察者匿名類、Record 替代備忘錄/訪問者數據載體
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved