設計模式是軟件工程的基石,是代碼復用、系統解耦、架構演進的核心武器庫。本文系統梳理 GoF 23 種經典設計模式,涵蓋創建型、結構型、行為型三大類別,輔以六大設計原則、UML 關係圖、完整 Java 實現代碼與應用場景分析,助你構建企業級開發的模式思維。
| 原則 | 核心思想 | 關鍵詞 |
|---|---|---|
| 開閉原則 (OCP) | 對擴展開放,對修改關閉 | 熱插拔、接口/抽象類 |
| 里氏替換原則 (LSP) | 子類必須能替換父類而不破壞功能 | 繼承復用基石、抽象化具體步驟 |
| 依賴倒置原則 (DIP) | 依賴抽象不依賴具體 | 面向接口編程、IOC 容器基礎 |
| 接口隔離原則 (ISP) | 多個專用接口優於單一臃腫接口 | 降低耦合、單一職責 |
| 迪米特法則 (LoD) | 最少知識原則,實體間盡量少交互 | 模塊獨立、降低依賴 |
| 合成復用原則 (CRP) | 優先組合/聚合,少用繼承 | 靈活復用、避免繼承爆炸 |
// 靜態工廠最佳實踐
public class SendFactory {
public static Sender produceMail() { return new MailSender(); }
public static Sender produceSms() { return new SmsSender(); }
}
// 使用:Sender sender = SendFactory.produceMail();
引入 Provider 接口,每種產品對應一個工廠實現,**新增產品只需新增工廠類,零修改現有代碼**,完美遵循 OCP。
從懶漢式 → 同步鎖 → 雙重檢查鎖 (DCL) → 靜態內部類 → 枚舉單例:
// 靜態內部類:JVM 保證線程安全 + 延遲加載 + 效能最優
public class Singleton {
private Singleton() {}
private static class Holder { static final Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance() { return Holder.INSTANCE; }
}
關鍵點:防反序列化破壞(實現 readResolve)、構造器拋異常處理、與靜態類的區別(可繼承、可實現接口、延遲加載)。
關注「復合對象」構建,將構建邏輯封裝在 Builder 中,適用於參數多、順序敏感、不可變對象構建。
// 深拷貝標準實現
public Object deepClone() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
return new ObjectInputStream(bis).readObject();
}
| 類型 | 核心機制 | 適用場景 |
|---|---|---|
| 類適配器 | 繼承 Source + 實現 Target | 單繼承限制,適配單一類 |
| 對象適配器 | 組合 Source 實例 + 實現 Target | 靈活適配多個對象,推薦 |
| 接口適配器 | 抽象類實現接口所有方法為空 | 接口方法過多,只需實現部分 |
裝飾對象持有被裝飾對象引用,**同一接口、靜態組合、可疊加**,解決繼承靜態、爆炸問題。
代理持有真實對象,**前置/後置增強**,實現 AOP 核心思想。Spring AOP 底層即動態代理實現。
Computer 封裝 CPU/Memory/Disk,**降低客戶端與子系統耦合**,類似 Spring 容器統一管理 Bean。
JDBC DriverManager 經典案例:**抽象接口 + 多種實現 + 橋接類持有實現引用**,實現運行時動態切換數據庫。
TreeNode 遞歸持有子節點,**葉子/容器統一接口**,適用於文件系統、組織架構、菜單樹。
數據庫連接池核心思想:**內部狀態共享 + 外部狀態參數化**,FlyweightFactory 管理對象池,大幅減少實例數量。
ICalculator 定義統一接口,Plus/Minus/Multiply 實現具體算法,**客戶端動態選擇策略**,適用於支付方式、排序算法、壓縮策略。
抽象類定義 final 模板方法調用抽象步驟,**子類只需實現變化點**,經典案例:HttpServlet.service() → doGet/doPost。
Subject 維護 Observer 列表,**狀態變更自動通知所有觀察者**,RSS 訂閱、事件總線、監聽器模式核心實現。
Collection 提供 iterator(),**封裝遍歷邏輯**,客戶端無需關心底層數據結構(數組/鏈表/樹)。
Handler 持有下一個 Handler,**請求在鏈上流轉直到被處理**,適用於過濾器鏈、審批流程、異常處理鏈。
Invoker 持有 Command,Command 持有 Receiver,**請求發送者與執行者完全解耦**,支援撤銷/重做、隊列/日誌記錄、Struts Action 核心思想。
Originator 創建 Memento,Caretaker 保存 Memento,**封裝內部狀態、不破壞封裝性**,適用於撤銷操作、事務回滾、遊戲存檔。
Context 持有 State,**狀態改變即行為改變**,QQ 在線/隱身/忙碌、訂單狀態機、工作流引擎核心模式。
Visitor 定義 visit(),Element 定義 accept(),**新增操作不修改數據結構**,適用於編譯器 AST 遍歷、報表導出多格式。
Mediator 統一管理 Colleague 交互,**對象間不直接引用**,類似機場塔台指揮、MVC 中 Controller、消息總線。
Expression 定義 interpret(),**遞歸組合終結符/非終結符**,適用於正則引擎、SQL 解析、規則引擎、計算器表達式求值。