Factory Method Pattern,PHP 工廠模式

man inside tool shed

簡介

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 pattern class diagram
咖啡工廠類別圖

優點

使用 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創建一系列相關的對象當需要創建多個相關或依賴的對象時

參考來源

  1. Wikipedia: Factory Method Pattern
  2. GeeksforGeeks: Factory Method Pattern
  3. Refactoring Guru: Factory Method
  4. Tutorialspoint: Factory Method Pattern
  5. Stack Overflow: What is Factory Method Pattern?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *