動態

詳情 返回 返回

學了設計模式,卻不知道怎麼選擇? - 動態 詳情

本人主要講述設計模式怎麼去選擇,這僅僅是不知從何下手提供一個抓手的東西,並不是銀彈。常想、多用,積累經驗後,方可靈活運用,做到無模式勝有模式,才可能會在複雜場景中,設計出高質量的系統。

設計模式的選擇是一個從問題到解決方案的遞進過程。通過明確問題類型、分析目標特性、遵循設計原則以及結合場景需求,可以高效地篩選出最佳設計模式,從而達到優化系統設計,提升代碼質量和可維護性。設計模式不僅是一種工具,更是一種面向對象程序設計的思維方式,能幫助開發者構建更加穩定和易於維護的軟件系統。

這篇文章花了挺多時間去整理的,還請耐心看完。

image

先説整體上,怎麼考慮,怎麼選擇。

1.設計模式選擇的綜合指南

1.1. 核心決策框架

  1. 問題驅動分類法

將系統問題歸類為三大場景,形成決策起點:

  • 創建型問題:對象如何誕生?(如電商購物車實例的全局唯一性 → 單例模式
  • 結構型問題:對象如何組織?(如動態擴展訂單附加服務 → 裝飾者模式
  • 行為型問題:對象如何協作?(如用户操作觸發多模塊聯動 → 觀察者模式
  1. 原則約束檢查表
    選擇模式時需通過設計原則驗證:
  • 單一職責:該模式是否讓每個類/模塊更專注?(如狀態模式分離狀態邏輯與主業務)
  • 開閉原則:新增功能是否無需修改既有代碼?(如裝飾者模式疊加功能不破壞原有結構)
  • 依賴倒置:是否通過接口而非具體實現交互?(如抽象工廠模式隔離具體產品類)
  • 里氏替換原則:具體實現類的切換是否影響程序正常使用?(如策略模式支持動態切換具體實現類)

1.2. 模式選擇進階策略

  1. 模式組合技
  • 動態創建+行為擴展:工廠方法+策略模式
    (示例:支付系統中,工廠創建支付處理器,策略模式切換算法)
  • 狀態管理+消息通知:狀態模式+觀察者模式
    (示例:訂單狀態變更時,自動觸發庫存更新和用户通知)
  1. 反模式預警

強調設計模式中設計思想的運用

陷阱 後果 解決方案
單例濫用 測試困難、隱藏依賴 依賴注入+工廠模式(如Spring框架)
過度裝飾者嵌套 調試鏈路複雜 合理控制層級,結合組合模式
觀察者內存泄漏 未及時取消訂閲 弱引用+生命週期管理
  1. 性能權衡指南
  • 空間換時間:享元模式共享對象減少內存重複--如遊戲中的樹木渲染共享紋理
  • 時間換靈活:代理模式增加間接層帶來性能損耗--需評估延遲是否在可接受範圍
  • 模式輕量化:函數式替代方案--如Lambda替代策略模式接口

2. 設計模式決策樹(23種)

細緻到每個設計模式的特點,通過問題類型和場景特徵,逐步定位適合的設計模式:

2.1. 第一步:確定核心問題類型

這個前面也已經提到過的了。

  1. 是否需要創建/管理對象?→ 創建型模式(6種)
  2. 是否需要組織對象結構? → 結構型模式(7種)
  3. 是否需要定義對象間協作?→ 行為型模式(11種)

2.2. 第二步:細化選擇路徑

1. 創建型模式(5種)

問題:如何高效、靈活地創建對象?

是否需要控制對象實例數量和提供全局訪問點?
├─ 是 → 單例模式(Singleton)
└─ 否 → 
   是否需要分步構造複雜對象?
   ├─ 是 → 建造者模式(Builder)
   └─ 否 → 
      是否通過克隆快速創建對象(避免高成本構造)?
      ├─ 是 → 原型模式(Prototype)
      └─ 否 → 
         是否需要在不暴露具體類的前提下,動態選擇實例化的類?
         ├─ 是 → 工廠方法模式(Factory Method)
         └─ 否 →
            是否需要創建一組相關對象,並確保它們協同工作?
            ├─ 是 → 抽象工廠模式(Abstract Factory)
            └─ 否 → 簡單工廠 或 直接創建

2. 結構型模式(7種)

問題:如何優化對象之間的組合與關係?

是否需要擴展對象功能且不影響現有代碼?
├─ 是 → 
   │ 是否需動態疊加功能?
   │ ├─ 是 → 裝飾者模式(Decorator)
   │ └─ 否 → 適配器模式(Adapter)
└─ 否 → 
   是否需要簡化複雜子系統?
   ├─ 是 → 外觀模式(Facade)
   └─ 否 → 
      是否需要解耦抽象與實現,以支持獨立變化?
      ├─ 是 → 橋接模式(Bridge)
      └─ 否 → 
         是否需要共享大量對象以減少內存資源?
         ├─ 是 → 享元模式(Flyweight)
         └─ 否 → 
            是否需要組合對象為樹形結構(“部分-整體”的層次關係)?
            ├─ 是 → 組合模式(Composite)
            └─ 否 → 
               是否需要代理控制訪問或優化性能?
               ├─ 是 → 代理模式(Proxy)
               └─ 否 → 

3. 行為型模式(11種)

問題:如何管理對象間的協作與責任分配?

是否需要動態切換一組算法?
├─ 是 → 策略模式(Strategy)
└─ 否 → 
   是否通過狀態驅動行為?
   ├─ 是 → 狀態模式(State)
   └─ 否 → 
      是否需要集中管理對象間複雜交互?
      ├─ 是 → 中介者模式(Mediator)
      └─ 否 → 
         是否需要支持請求的撤銷/重做?
         ├─ 是 → 備忘錄模式(Memento)
         └─ 否 → 
            是否需要將請求封裝為對象(支持參數化、隊列化)?
            ├─ 是 → 命令模式(Command)
            └─ 否 → 
               是否需要被觀察的對象變化後,會自動通知多個訂閲者?
               ├─ 是 → 觀察者模式(Observer)
               └─ 否 → 
                  是否需要由多個對象依次處理請求?
                  ├─ 是 → 責任鏈模式(Chain of Responsibility)
                  └─ 否 → 
                     是否需要定義操作步驟/算法骨架,並允許子類重寫具體細節?
                     ├─ 是 → 模板方法模式(Template Method)
                     └─ 否 → 
                        是否需要遍歷集合對象?
                        ├─ 是 → 迭代器模式(Iterator)
                        └─ 否 → 
                           是否需要分離數據結構和操作行為?
                           ├─ 是 → 訪問者模式(Visitor)
                           └─ 否 → 
                              是否需要解釋和處理某種語言或表達式的語法規則?
                              ├─ 是 → 解釋器模式(Interpreter)
                              └─ 否 → 

注:行為型模式的選擇並無嚴謹的先後順序。

2.3. 決策樹使用建議

設計模式決策樹的核心邏輯是:

問題分類目標匹配原則驗證
在實際開發中需結合具體場景靈活調整,最終目標是寫出高內聚、低耦合、可重用、易擴展易維護高性能的代碼。 通過刻意練習(如重構既有代碼、閲讀框架源碼),可逐步培養模式選擇的直覺。

避免教條主義:模式是工具而非規則,例如簡單場景無需強制使用設計模式,而複雜場景需要多種模式相互配合和模式創新。

3. 總結

設計模式的選擇如同烹飪調味——需要根據食材特性(系統需求)、食客口味(團隊能力)、廚房條件(技術棧)綜合決策。關鍵在於:

  1. 保持問題敏感度:從代碼異味(如巨型類、擴散式修改)中發現模式應用契機
  2. 掌握模式本質:理解模式背後的抽象原則而非具體實現
  3. 培養架構直覺:通過閲讀優秀源碼(如Spring、Netty)積累模式使用經驗

最終目標不是成為模式的奴隸,而是讓模式成為手中游刃有餘的設計語言,構建出兼具彈性簡潔性的軟件系統。

通過項目開發,積累經驗後,你會逐漸能根據項目的具體需求,靈活運用合適的設計模式。

image

需要查看往期設計模式文章的,可以在個人主頁中或者文章開頭的集合中查看,可關注我,持續更新中。。。
後續會分享

秘籍1>>掌握設計模式:23種經典模式實踐、選擇、價值與思想.pdf

秘籍2>>設計模式實戰項目:markdown文本編輯器軟件開發(開放所有源代碼


超實用的SpringAOP實戰之日誌記錄

2023年下半年軟考考試重磅消息

通過軟考後卻領取不到實體證書?

計算機算法設計與分析(第5版)

Java全棧學習路線、學習資源和麪試題一條龍

軟考證書=職稱證書?

軟考中級--軟件設計師毫無保留的備考分享

user avatar kuailedehuanggua 頭像 buguge 頭像 seven97_top 頭像
點贊 3 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.