2026年10月20日 星期二

GoF(Gang of Four)的《Design Patterns》23 種設計模式的適用情境

 GoF(Gang of Four)的《Design Patterns》將 23 種經典設計模式分為三大類(創建型、結構型、行為型)。軟體工程界與許多經典著作(如 Martin Fowler 的重構書籍、Refactoring.guru、以及各種架構指南)早已將每種模式歸納出明確的適用情境(Use Cases)與解決的問題。


以下為您系統化整理這 23 種設計模式的適用情境:


一、 創建型模式 (Creational Patterns)


主要用於處理物件的建立機制,將「物件的建立與使用」解耦。

設計模式核心目的適合情境
Simple Factory (非 GoF 23式,但常與之並列)封裝物件建立邏輯建立邏輯簡單、類型數量有限,呼叫端不想直接 new 具體類別時。
Factory Method (工廠方法)子類別決定要實例化哪一個類別類別無法預期必須建立的物件類別(或希望由子類別來決定具體型別),例如框架中的插件機制。
Abstract Factory (抽象工廠)建立一系列相關或相依物件的介面系統需要獨立於其產品的建立、組合和表示時,且產品家族需要一起使用(例如支援多種 UI 主題或資料庫介面)。
Builder (建造者模式)分步驟建立複雜物件物件包含許多繁複的屬性,且建構過程必須分步驟進行,或需要產生不同表示法的複雜物件(避免過長的建構子參數)。
Prototype (原型模式)透過複製現有物件來建立新物件建立物件的成本非常高(例如需要讀取資料庫或複雜運算),或動態決定執行時期物件型別時。
Singleton (單例模式)確保一個類別只有一個實例,並提供全域存取點系統只需要一個共用資源管理器(如連線池、設定檔讀取器、記錄器 Logger)。 (註:現代架構常搭配 DI 框架使用以降低耦合)

二、 結構型模式 (Structural Patterns)


主要用於組合類別與物件,形成更大的結構。

設計模式核心目的適合情境
Adapter (轉接器模式)轉換介面,讓不相容的類別協同運作想使用一個現有的類別,但其介面(方法名稱、參數)與系統現行規範不符(例如整合第三方 SDK)。
Bridge (橋接模式)將抽象與實作解耦,讓兩者可以獨立變化系統有多個維度的變化(例如「形狀」與「顏色」),若使用繼承會導致子類別爆炸,改用組合來分離。
Composite (組合模式)將物件組合成樹狀結構以表示「部分-整體」客戶端需要一致地對待單一物件與物件組合(例如檔案系統中的檔案與資料夾)。
Decorator (裝飾者模式)動態地將職責附加到物件上需要在不修改原類別的前提下,動態、透明地擴充物件的功能(例如 Java I/O 串流包裝)。
Facade (外觀模式)提供統一的高階介面來存取子系統系統複雜、相依關係龐大,希望提供一個簡單、單一的進入點給客戶端使用。
Flyweight (輕量級模式)運用共用技術有效地支援大量細粒度物件系統中存在大量相同或相似的物件,導致記憶體消耗過大,透過共用狀態來節省記憶體(例如文字編輯器中的字型字元)。
Proxy (代理模式)為其他物件提供一個替身以控制存取無法或不希望直接存取目標物件時,透過代理來控制權限、延遲載入(Lazy Loading)、或加入快取/記錄。

三、 行為型模式 (Behavioral Patterns)


主要用於處理物件之間的演算法與職責分配。

設計模式核心目的適合情境
Chain of Responsibility (責任鏈模式)將請求沿著處理者鏈傳遞直到被處理有多個物件可以處理同一個請求,但具體由誰處理在執行時期才決定(例如 Web 伺服器的 Middleware 驗證管線)。
Command (命令模式)將請求封裝成物件需要將動作參數化、支援排隊執行(Queue)、撤銷/重做(Undo/Redo)、或記錄日誌。
Interpreter (直譯器模式)定義語言的文法並建立直譯器有一個簡單的語言或規則需要評估(例如正規表達式、特定業務規則 DSL),且其文法結構可以表示為抽象語法樹。
Iterator (迭代器模式)順序存取聚合物件中的元素,不暴露其內部結構需要提供多種走訪集合的方式,同時隱藏集合內部的底層資料結構(如陣列、樹、雜湊表)。
Mediator (中介者模式)用一個中介物件來封裝一組物件的互動多個物件之間呈現複雜的網狀相依(許多對許多),透過引入中介者將其轉為星狀相依(一對多),簡化通訊。
Memento (備忘錄模式)在不破壞封裝性的前提下,擷取並保存物件內部狀態需要實現資料的快照、還原、或 Undo 機制,但又不能暴露物件內部的實作細節。
Observer (觀察者模式)定義物件間的一對多相依,當狀態改變時自動通知當一個物件的狀態改變時,需要同步通知其他多個相依物件,且不希望這些物件之間產生緊密耦合(例如事件驅動架構、UI 資料繫結)。
State (狀態模式)允許物件在其內部狀態改變時改變行為物件的行為取決於其當前狀態,且程式碼中充滿了大量的 if-else 或 switch-case 來判斷狀態轉換。
Strategy (策略模式)定義一系列演算法,並讓它們可以互相替換同一個業務邏輯有多種不同的實作方式(例如不同的折扣計算、不同的排序或導航路徑演算法),且希望在執行時期動態切換。
Template Method (樣版方法模式)在父類別中定義演算法骨架,將特定步驟延遲到子類別多個類別擁有相似的執行流程,但部分細節步驟不同,透過繼承抽離共用邏輯,避免程式碼重複。
Visitor (訪問者模式)在不改變類別的前提下定義新操作一個穩定的物件結構(少變動的類別階層)需要對其執行許多截然不同且經常變動的操作。

💡 實務建議


在實際開發中,許多設計模式往往不是單獨出現的:

  • MVC / MVVM 架構大量運用了 Observer(資料繫結)、Strategy(驗證器/排版)、Composite(視圖樹)。

  • 當狀態邏輯變得複雜時,常會結合 State 與 Strategy。

  • 當需要建立複雜且具有變異性的物件時,會結合 Builder 與 Abstract Factory。

如果要深入查閱特定模式的 UML 結構與程式碼範例(支援 Java、C++、Python、C# 等多種語言),推薦參考業界標準的 Refactoring.guru,其情境對比與優缺點分析非常直觀。

沒有留言:

張貼留言

有 Creational Patterns 的原因,是否是有些狀況不適合直接用 new 建造出一個物件來用?

  沒錯!您的直覺非常準確,這正是整個創建型模式(Creational Patterns)核心要解決的根本問題。 在軟體開發中,直接使用 new 關鍵字來建立物件(例如 MyClass obj = new MyClass(); )雖然直覺又方便,但在中大型系統或需要高度擴充性的...