概述#
Creational pattern 抽象化了物件的實例化過程(instantiation process),使系統不依賴於物件如何被建立、組合和表示。其中:
- Class creational pattern 使用繼承來改變被實例化的 class
- Object creational pattern 將實例化委託給另一個物件
隨著系統演進,越來越依賴**物件組合(object composition)**而非 class 繼承,creational pattern 的重要性也隨之增加——建立具有特定行為的物件不再只是簡單地實例化一個 class。
兩個核心主題#
所有 creational pattern 都圍繞著兩個反覆出現的主題:
- 封裝具體 class 的知識:系統只透過 abstract class 定義的介面認識物件
- 隱藏實例的建立與組裝方式:提供極大的彈性來決定 what(建立什麼)、who(誰來建立)、how(如何建立)、when(何時建立)
Creational pattern 之間有時是競爭者(例如 Prototype 和 Abstract Factory 可互相替代),有時是互補的(例如 Builder 可以使用其他 pattern 來決定建造哪些元件,Prototype 可以在實作中使用 Singleton)。
Maze 範例#
本書使用一個共通範例——電腦遊戲中的迷宮(maze)——來展示各個 creational pattern 的實作差異。
迷宮由以下元件組成:
MapSite:所有迷宮元件的共同抽象 class,定義Enter操作Room:MapSite的具體子類別,維護四面的鄰居參照與房間編號Wall和Door:出現在房間各面的牆壁或門Maze:房間的集合,可透過RoomNo找到特定房間MazeGame:建立迷宮的 class
直接在 CreateMaze 中硬編碼建立流程的問題是缺乏彈性——想要改變迷宮元件(例如 EnchantedRoom、DoorNeedingSpell)就必須修改整個函式。
五種 Creational Pattern 的解法#
各 pattern 以不同方式移除對具體 class 的顯式參照:
| Pattern | 解法 |
|---|---|
| Factory Method | CreateMaze 呼叫 virtual function 而非 constructor,透過子類別化 MazeGame 來改變實例化的 class |
| Abstract Factory | 將建立物件的工廠作為參數傳入 CreateMaze,替換不同的工廠就能改變元件類型 |
| Builder | 傳入一個能用操作逐步建造迷宮的物件,可透過繼承改變建造方式或元件 |
| Prototype | 以各種原型物件(prototypical room、door、wall)參數化 CreateMaze,透過複製原型來建立新元件 |
| Singleton | 確保每個遊戲只有一個 maze 實例,所有遊戲物件都能存取它,且不需依賴全域變數 |