簡介
Factory Method Pattern 專門用於處理物件創建的問題。本文會先解釋什麼是 Factory Method Pattern,然後用一個簡單易懂的例子來說明它。接著說明什麼情況下應該使用這個模式,並通過一個以咖啡為主題的 PHP 程式範例來進一步說明。最後比較 Factory Method Pattern 和其他類似的設計模式。
什麼是 Factory Method Pattern
Factory Method Pattern 是一種創建型設計模式,它提供了一個介面用於創建物件,但允許子類別改變將要創建的物件的類型。這樣,我們可以將物件創建的代碼和實際使用物件的代碼分離,增加了代碼的靈活性和可維護性。
想像你走進一家咖啡店,你不需要知道咖啡是如何製作的,你只需要點單。咖啡店(Factory)會根據你的需求(參數)為你製作一杯咖啡(物件)。
什麼狀況適合使用 Factory Method Pattern
當你有一個超類別,它有多個子類別,並且基於某些條件,你必須返回其中一個子類別的實例時,最好使用 Factory Method Pattern。這樣可以隱藏實例創建的邏輯,並使代碼更容易擴展。例如,一個咖啡店可能有多種咖啡,每種咖啡的製作過程都略有不同。使用 Factory Method,我們可以輕鬆地新增更多種咖啡,而不影響現有代碼。
範例教學
在這個範例中,我們會創建一個 CoffeeFactory
類別,它可以製作不同種類的咖啡。
原始範例,未使用 Factory Method
<?php
class Coffee {
public function brew() {
echo "Brewing a regular coffee\n";
}
}
$coffee = new Coffee();
$coffee->brew();
?>
缺點
這種方式的主要缺點是它不夠靈活。如果我們想添加更多種咖啡,必須自己創建物件實體,如果使用工廠模式,就不必深入了解各種不同的咖啡,降低物件間的耦合。
改善範例,使用 Factory Method
<?php
interface Coffee {
public function brew();
}
class RegularCoffee implements Coffee {
public function brew() {
echo "Brewing a regular coffee\n";
}
}
class Espresso implements Coffee {
public function brew() {
echo "Brewing an espresso\n";
}
}
class CoffeeFactory {
public static function createCoffee($type) {
if ($type === 'regular') {
return new RegularCoffee();
} elseif ($type === 'espresso') {
return new Espresso();
}
}
}
$coffee = CoffeeFactory::createCoffee('espresso');
$coffee->brew();
?>
優點
使用 Factory Method,我們可以輕鬆地添加更多種咖啡,而不會依賴咖啡的實際類別。
更多延伸範例
我們可以繼續擴展這個範例,例如添加一個 Latte
類別。
class Latte implements Coffee {
public function brew() {
echo "Brewing a latte\n";
}
}
// 更新 CoffeeFactory
class CoffeeFactory {
// ...
public static function createCoffee($type) {
// ...
elseif ($type === 'latte') {
return new Latte();
}
}
}
// 工廠現在可以生產拿鐵,使用者只需知道拿鐵的名稱就好,看不到工廠背後的運作。
$coffee = CoffeeFactory::createCoffee('latte');
$coffee->brew();
其他類似的 Design Pattern
Factory Method Pattern 和 Abstract Factory Pattern 都是用於創建對象的。主要區別在於,Factory Method 是用於創建單一類型的對象,而 Abstract Factory 是用於創建一系列相關或依賴的對象。
Design Pattern | 主要用途 | 適用情境 |
---|---|---|
Factory Method | 創建單一類型的對象 | 當需要根據條件創建不同類型的對象時 |
Abstract Factory | 創建一系列相關的對象 | 當需要創建多個相關或依賴的對象時 |