前言:為什麼要重溫設計模式?
在展開更大型的專案之前,我決定先複習一下設計模式的功課。閱讀《Head First Design Patterns》關於 Decorator 模式的試閱章節時,我不禁感嘆:JOLT 大獎確實名不虛傳。這本書的敘事能力極強,表達清晰透徹,絕非那些滿腹經綸的前輩著作可比。更難得的是,整個模式的講述過程循序漸進,真正做到了「小白也能學會設計模式」。
遺憾的是手邊只有試閱章節,Head First 系列的電子書向來難覓,只好翻出前輩們的經典著作繼續鑽研。這次複習進行得很快,因為我發現 GoF 80% 的模式,其實都建立在同一個核心原則之上:
核心原則:優先使用物件組合,而非類別繼承
初學 OO 的人習慣用現實世界映射程式世界,繼承是最自然的直覺。但 GoF 的真正用意,正是要扭轉這種思維,讓開發者習慣使用組合、委派與介面導向程式設計。只要掌握兩大組合機制原理,就能演變出絕大多數 GoF 模式:
原則一:任何耦合皆可透過增加中介層解耦
代表模式:Facade、Mediator、Adapter、Factory/Abstract Factory、Proxy
- Facade:降低系統間內部類別的耦合,建立代理物件封裝主要功能
- Mediator:降低兩物件間耦合,引入中介物件同時持有雙方實例
- Adapter:讓不同物件使用統一介面,建立代理物件轉換介面
- Factory:不依賴具體物件創建,而是依賴介面透過工廠獲取物件
- Proxy:除解耦外,還能在調用過程中插入額外邏輯(AOP 思想雛形)
原則二:透過組合擴充物件特性,避免純繼承導致的類別爆炸
代表模式:Bridge、Decorator、Chain of Responsibility、Strategy/Command
- Bridge:當物件特徵向兩個維度發展時(如杯型:大/中、配料:加奶/加糖),將一組特徵抽象為介面注入主繼承樹,避免排列組合爆炸
- Decorator:透過包裝原物件為其動作添加新行為。新類別繼承原類別,持有原物件實例,調用時先執行原邏輯再擴充新功能
- Chain of Responsibility:建立職責鏈,各物件持有下一節點引用,按情況處理後傳遞控制權。Apache Jakarta Commands 提供 chains 庫實現
- Strategy/Command:Template Method 的對立面,將演算法/行為封裝為物件進行組合
其他常用獨立模式
- Singleton:確保全域單一實例
- Visitor:讓獨立物件遍歷組合結構執行操作,雙重分派機制(accept/visit)稍顯不夠優雅
- Observer:監控物件狀態變化的機制,JDK 內建兩套介面輔助實現
個人重溫筆記:模式核心機制速查
- Facade:建立物件 A 代理系統核心功能,隔離內部複雜度
- Mediator:建立中介物件 C 持有 A、B 實例,並將 C 注入 A、B 解除直接依賴
- Adapter:建立物件 B 代理 A 並轉換介面以匹配目標介面
- Factory:程式碼依賴介面而非具體類別,透過 Factory 獲取實例
- Proxy:在代理調用中插入橫切邏輯(權限、日誌、交易等),AOP 核心思想
- Bridge:將變化維度抽象為介面,透過組合而非繼承組合變化
- Decorator:包裝模式,同介面、持有被裝飾者、調用鏈式擴充
- COR:鏈式處理,各節點決定是否處理並傳遞給下一節點
- Strategy/Command:行為物件化,支援執行時動態切換演算法
- Observer:發布-訂閱機制,JDK 提供 Observable/Observer 支援
- Visitor:雙重分派,元素接受訪問者並在 accept 中回調 visit(this)
這些筆記是寫給未來的自己看的「慢動作重播」。設計模式不是死記硬背的模板,而是解決特定耦合與變化問題的思維工具。真正掌握的標誌,是能在面對新問題時,自然地想到「這是不是可以用組合加個中介層解決?」或「這兩個維度的變化是不是該用 Bridge 分離?」——這才是 GoF 留給我們最寶貴的遺產。