設計模式(Design Pattern)是軟件開發中針對常見問題的經典解決方案,由 GoF(Gang of Four)在《設計模式:可復用面向對象軟件的基礎》一書中歸納為23 種模式,分為三大類:創建型模式、結構型模式和行為型模式。以下是它們的分類、區別和作用詳解:
一、創建型模式(Creational Patterns)
核心作用:封裝對象的創建邏輯,分離對象的創建和使用,使系統更靈活地創建不同類型的對象。
包含模式:
-
工廠方法模式(Factory Method)
- 作用:定義一個創建對象的接口,由子類決定實例化哪個具體類。
- 區別:將簡單工廠的靜態創建邏輯改為動態(通過子類實現),符合開閉原則。
- 場景:創建對象的邏輯需要延遲到子類實現時(如日志工廠、數據庫連接工廠)。
-
抽象工廠模式(Abstract Factory)
- 作用:創建一組相關或依賴的對象(如跨平臺 UI 組件:按鈕、文本框的組合)。
- 區別:比工廠方法更復雜,用于創建多個產品族(如同時創建 Windows 和 Mac 的 UI 組件)。
-
單例模式(Singleton)
- 作用:確保一個類只有一個實例,并提供全局訪問點(如線程池、日志管理器)。
- 區別:通過私有化構造函數、靜態實例和線程安全機制實現。
-
原型模式(Prototype)
- 作用:通過復制現有對象創建新對象,避免重復初始化邏輯(如配置對象克隆)。
- 區別:基于對象克隆(實現
Cloneable
接口),適用于創建成本較高的對象。
-
建造者模式(Builder)
- 作用:將復雜對象的構建過程分解為多個步驟,允許不同的構建順序(如創建用戶對象:姓名、年齡、地址分步設置)。
- 區別:分離對象的構建和表示,適合參數多且組合復雜的對象。
二、結構型模式(Structural Patterns)
核心作用:簡化對象間的結構關系,優化類或對象的組合方式,提高系統的靈活性和可維護性。
包含模式:
-
適配器模式(Adapter)
- 作用:將一個類的接口轉換為另一個接口,使不兼容的類可以協同工作(如電源適配器轉換電壓)。
- 區別:分為類適配器(繼承)和對象適配器(組合),后者更常用。
-
裝飾器模式(Decorator)
- 作用:動態地給對象添加新功能,避免繼承導致的類爆炸(如咖啡飲品添加調料:牛奶、糖漿)。
- 區別:通過組合方式擴展功能,比繼承更靈活(開閉原則)。
-
代理模式(Proxy)
- 作用:為其他對象提供一個代理或占位符,控制對原對象的訪問(如遠程代理、緩存代理、權限代理)。
- 區別:代理對象與原對象實現相同接口,客戶端透明調用。
-
外觀模式(Facade)
- 作用:為復雜子系統提供一個統一的接口,簡化客戶端調用(如整合支付系統的統一入口)。
- 區別:降低客戶端與子系統的耦合,屬于結構型模式中的 “簡化接口” 模式。
-
橋接模式(Bridge)
- 作用:將抽象部分與實現部分分離,使它們可以獨立變化(如將 “消息類型” 與 “發送方式” 解耦)。
- 區別:通過組合而非繼承實現抽象和實現的分離,適用于多維度變化的場景。
-
組合模式(Composite)
- 作用:將對象組合成樹形結構,表示 “部分 - 整體” 的層次關系(如文件系統:文件夾包含文件和子文件夾)。
- 區別:統一處理單個對象(葉子節點)和組合對象(容器節點),簡化層次操作。
-
享元模式(Flyweight)
- 作用:共享多個對象的公共狀態,減少內存占用(如文本編輯器中的字符共享字體、顏色等公共屬性)。
- 區別:通過分離 “內部狀態”(共享)和 “外部狀態”(不共享)優化性能。
三、行為型模式(Behavioral Patterns)
核心作用:關注對象間的通信和算法設計,優化對象之間的交互流程,提升系統的靈活性和可擴展性。
包含模式:
-
策略模式(Strategy)
- 作用:定義一系列算法,將每個算法封裝起來,使它們可以相互替換(如電商促銷策略:滿減、折扣、贈品)。
- 區別:通過接口實現算法族,運行時動態切換策略,避免多重條件判斷。
-
模板方法模式(Template Method)
- 作用:在抽象類中定義算法骨架,具體步驟由子類實現(如 HTTP 請求處理模板:預處理→處理→后處理)。
- 區別:通過繼承強制子類實現某些步驟,屬于 “頂層設計” 模式。
-
觀察者模式(Observer)
- 作用:定義對象間的一對多依賴關系,當一個對象狀態改變時,所有依賴者自動更新(如訂閱 - 發布系統、股市行情通知)。
- 區別:通過注冊 / 注銷機制解耦主題(Subject)和觀察者(Observer)。
-
迭代器模式(Iterator)
- 作用:提供一種遍歷集合元素的統一方式,無需暴露集合內部結構(如 Java 的
Iterator
接口)。 - 區別:分離集合的遍歷邏輯,支持不同的遍歷方式(正向、反向、跳躍遍歷)。
- 作用:提供一種遍歷集合元素的統一方式,無需暴露集合內部結構(如 Java 的
-
責任鏈模式(Chain of Responsibility)
- 作用:將請求的發送者和處理者解耦,請求沿著鏈傳遞,直到有一個處理者處理(如審批流程:組長→經理→總監)。
- 區別:避免請求發送者與具體處理者耦合,動態調整鏈的順序。
-
命令模式(Command)
- 作用:將 “請求” 封裝為對象,使請求發送者和接收者解耦(如撤銷操作、日志記錄、線程池任務)。
- 區別:通過命令對象(Command)封裝動作,支持隊列化、撤銷等操作。
-
備忘錄模式(Memento)
- 作用:在不破壞封裝性的前提下,捕獲對象的內部狀態并保存,以便恢復(如游戲存檔、編輯器撤銷)。
- 區別:通過備忘錄(Memento)對象保存狀態,由負責人(Caretaker)管理。
-
狀態模式(State)
- 作用:允許對象在內部狀態改變時改變行為,對象看起來像是修改了類(如電梯狀態:運行、停止、故障)。
- 區別:將狀態邏輯封裝為獨立的狀態類,避免大量條件判斷。
-
訪問者模式(Visitor)
- 作用:將數據結構與作用于結構上的操作解耦,使操作可以獨立擴展(如統計文件系統中不同類型文件的大小)。
- 區別:通過訪問者(Visitor)類定義操作,數據結構(如元素 Element)負責接待訪問者。
-
中介者模式(Mediator)
- 作用:通過中介者對象封裝對象間的交互邏輯,避免對象直接引用(如聊天房間中介協調用戶消息傳遞)。
- 區別:減少對象間的直接依賴,將多對多交互轉換為一對多(對象與中介者)。
-
解釋器模式(Interpreter)
- 作用:給定一種語言,定義其文法的表示,并定義一個解釋器來解釋語言中的句子(如正則表達式引擎、數學表達式解析)。
- 區別:適用于需要頻繁改變文法或解釋規則的場景,實現成本較高。
四、三大類模式的核心區別
類型 | 關注重點 | 典型場景 | 關鍵作用 |
---|---|---|---|
創建型 | 對象的創建方式 | 復雜對象初始化、對象池、單實例 | 解耦對象創建與使用,控制實例化邏輯 |
結構型 | 對象的組合與結構關系 | 接口轉換、動態擴展、層次結構 | 優化系統結構,簡化對象間的依賴關系 |
行為型 | 對象間的交互與算法設計 | 流程控制、狀態管理、消息傳遞 | 解耦對象交互邏輯,提升系統靈活性 |
五、常見模式:
創建型模式(Creational Patterns)
核心目標:封裝對象的創建過程,將對象的創建與使用分離,提高系統的靈活性和可擴展性。
特點:
- 隱藏對象創建的復雜邏輯。
- 通過接口或抽象類定義創建規范,由子類或具體實現決定具體創建方式。
模式名稱 | 作用與特點 | 應用場景示例 |
---|---|---|
單例模式(Singleton) | 確保一個類只有一個實例,并提供全局訪問點。 | 數據庫連接池、配置管理器。 |
工廠模式(Factory Method) | 定義對象創建的接口,子類決定具體實例化哪個類。 | 支付網關(根據支付類型創建不同支付處理器)。 |
抽象工廠模式(Abstract Factory) | 創建相關或依賴對象的家族,無需指定具體類。 | GUI框架(創建跨平臺的按鈕、文本框等組件)。 |
建造者模式(Builder) | 將復雜對象的構建與其表示分離,逐步構建對象。 | 生成復雜配置文件(如XML、JSON)。 |
原型模式(Prototype) | 通過復制現有對象創建新對象,避免重復初始化。 | 克隆配置對象、快速生成相似數據。 |
結構型模式(Structural Patterns)
核心目標:組合類或對象的結構,形成更大的結構,簡化系統設計并提高靈活性。
特點:
- 通過繼承、組合或聚合等方式,定義類或對象之間的關系。
- 關注如何高效地組織代碼結構,優化系統的可維護性。
常見模式:
模式名稱 | 作用與特點 | 應用場景示例 |
---|---|---|
適配器模式(Adapter) | 將不兼容的接口轉換為兼容的接口,使原本不兼容的類可以協作。 | 舊系統接口與新系統對接。 |
裝飾器模式(Decorator) | 動態地為對象添加額外功能,比繼承更靈活。 | 給咖啡加糖、奶泡(動態擴展功能)。 |
代理模式(Proxy) | 為對象提供代理,控制對原始對象的訪問(如權限校驗、延遲加載)。 | 遠程調用、緩存代理。 |
外觀模式(Facade) | 為子系統提供統一接口,簡化復雜系統的調用。 | 一鍵啟動電腦(調用多個硬件組件)。 |
組合模式(Composite) | 將對象組合成樹形結構,表示“部分-整體”的層次關系。 | 文件系統(文件夾包含文件和子文件夾)。 |
行為型模式(Behavioral Patterns)
核心目標:定義對象之間的交互和職責分配,提高對象間的協作效率。
特點:
- 關注對象之間的通信方式(如事件、回調、鏈式調用)。
- 解耦對象之間的依賴關系,增強系統的可維護性。
模式名稱 | 作用與特點 | 應用場景示例 |
---|---|---|
觀察者模式(Observer) | 定義對象間的一對多依賴關系,當狀態變化時通知所有依賴對象。 | 事件驅動系統(如GUI事件監聽)。 |
策略模式(Strategy) | 將算法封裝為獨立類,允許在運行時動態切換策略。 | 支付系統(支持多種支付方式)。 |
責任鏈模式(Chain of Responsibility) | 將請求的發送者和接收者解耦,多個對象依次處理請求。 | HTTP請求過濾器鏈(如權限校驗、日志記錄)。 |
命令模式(Command) | 將請求封裝為對象,支持參數化請求、隊列操作和撤銷功能。 | 撤銷/重做功能(如文本編輯器)。 |
狀態模式(State) | 允許對象在內部狀態改變時改變行為,避免冗長的條件判斷。 | 狀態機(如訂單狀態:待支付、已發貨、已完成)。 |
六、總結
設計模式是軟件開發的 “最佳實踐”,其本質是通過抽象和封裝解決特定問題。學習時需注意:
- 理解場景:每種模式都有適用場景,避免為了用模式而用模式。
- 對比差異:如工廠方法與抽象工廠、裝飾器與適配器的區別,需結合具體需求選擇。
- 結合語言特性:如 Java 的接口、繼承、反射等機制會影響模式的實現方式(如單例的線程安全實現)。
通過實際項目練習,逐步掌握不同模式的應用,可以顯著提升代碼的可維護性、可擴展性和復用性。