本章主軸#
工廠方法模式(Factory Method)讓一個基底類別定義「應該建立某種物件」這件事,但把「建立哪一種具體類別」的決定權留給子類。它是建立平行類別階層、實作框架(framework)、串接 Template Method 的標準工具。
案例:Template Method 與資料庫實例化#
延續第 19 章。QueryTemplate.doQuery() 內需要建立資料庫物件。誰來建?
- 不適合交給 Client,否則 Client 必須認識每種資料庫
- 把它做成
QueryTemplate的抽象方法makeDB(),由OracleQT、SQLSvrQT等子類各自決定要 new 哪個物件——這就是 Factory Method
GoF 對 Factory Method 的意圖描述#
為建立物件定義一個介面,但讓子類別決定要實例化哪個類別。Factory Method 把實例化的決定延遲到子類別。
公開還是受保護?#
makeDB() 通常是 protected——只給 QueryTemplate 體系自己用。如果你希望外界也能呼叫,就改 public。
主要語言中的應用#
| 語言 | 例子 |
|---|---|
| Java | Collection.iterator() 為集合建立對應的 iterator |
| C# | IEnumerable.GetEnumerator() |
| C++ | begin() / end() |
這些都是 Factory Method 的具體展現——由集合自己決定要回傳哪種 iterator。
Factory Method 的關鍵特性#
| 欄位 | 內容 |
|---|---|
| Intent | 為建立物件定義介面,由子類決定 new 哪個 |
| Problem | 一個類別需要實例化某類別的衍生型別,但自己不知道是哪一種 |
| Solution | 把建立工作下放到子類 |
| Participants | Product(被建立的物件介面)、Creator(定義 Factory Method 的介面) |
| Consequences | Client 想用新的 Product,需 subclass Creator |
| Implementation | 抽象類別中以 abstract / pure virtual 方式宣告建立方法,由子類實作 |
實務筆記#
Abstract Factory 可由一群 Factory Method 構成#
GoF 經典實作中的 Abstract Factory,每個 method 其實都是一個 Factory Method。
綁定平行類別階層#
當你有兩棵類別樹(如集合 vs iterator),且新增集合就需要新增對應 iterator,Factory Method 是最自然的綁定方式。每棵樹的對應節點互相成對,由 Factory Method 在原 hierarchy 上把對應 hierarchy「指出來」。
Framework 的招牌用法#
框架本質上活在抽象層次,不知也不該知具體型別。
Factory Method 讓框架把「具體實例化」交給用框架的人,是其常見、必然的選擇。
本章重點#
- Factory Method 把「new 哪一個」這個決定交給子類
- 它是 Template Method、Abstract Factory、Iterator 等模式的共同建構塊
- 在實作框架時,Factory Method 是把控制權「反轉」回應用方的標準手法