今天我們會介紹 factory method 模式。
起手式:丟出案例。
我們在 DAY18 中講到了一個案例:
系統要能夠支援 Oracle 與 SQL Server 資料庫。雖然兩者都基於能夠使資料庫使用更加簡單的通用標準 SQL。
我們現在有新的問題:如何對目前背景所需的資料庫物件實體化。我們希望的會是把這個責任指派給 QueryTemplate
類別自己。
本例的 QueryTemplate
類別,我們想讓它的每個衍生類別負責實體化與自己對應的資料庫,無論 QueryTemplate
及其衍生類別是否是唯一使用資料庫的類別。我們的做法會是如下圖。
在圖中,template method 模式中的 doQuery()
使用 makeDB()
實體化相關物件。QueryTemplate
並不知道要實體化哪個資料庫物件;它只知道肯定有一個資料庫物件必須要實體化,而且要為其實體化提供一個介面。
在這個層次上,我們可以將如何實體化資料庫的決策推遲到衍生類別的某個方法中。
GoF 對這個模式是這樣描述的:
定義一個用於建立物件的介面,讓子類別決定實體化哪一個類別。Factory Method 使一個類別的實體化延遲到其子類別。
項目 | 內容 |
---|---|
意圖 | 定義一個用於建立物件的介面,讓子類別決定實體化哪一個類別。將實體化推遲到子類別。 |
問題 | 一個類別需要實體化另一個類別的衍生類別,但不知道是哪一個。Factory method 允許衍生類別進行決策。 |
解決方案 | 衍生類別對實體化哪個類別和如何實體化做出決策 |
參與者與協作者 | Product 是工廠方法所建立的物件類型的介面。Creator 是定義工廠方法的介面 |
效果 | 客戶將需要衍生 Creator ,以建立一個特定的 ConcreteProduct 物件。 |
實作 | 在抽象類別中使用一個抽象方法。需要實體化一個被包含物件的時候抽象類別的程式碼將參照此方法,但是不知道需要的物件是哪一個。 |
以下是 UML 圖: