工廠模式的核心價值在於「封裝物件建立過程」。不再直接使用 new 硬編碼具體類別,而是透過工廠方法或抽象工廠統一管理實例化邏輯,大幅降低耦合,提升擴展性。
| 類型 | 產品範圍 | 結構特點 | 適用場景 |
|---|---|---|---|
| 簡單工廠 | 單一產品族 | 一個工廠類,靜態方法根據參數返回實例 | 產品種類固定、建立邏輯簡單 |
| 工廠方法 | 單一產品族 | 抽象工廠定義介面,子類決定實例化哪個類 | 需延遲到子類決定具體實現 |
| 抽象工廠 | 多個產品族 | 提供介面創建一系列相關/相依物件,無需指定具體類 | 系統需支援多種產品系列(如跨資料庫、跨平台) |
<?php
// 產品介面
interface DB {
public function connect(): void;
public function exec(string $sql): void;
}
// 具體產品
class MysqlDB implements DB {
public function __construct() { echo "MySQL DB 已建立\n"; }
public function connect(): void { /* ... */ }
public function exec(string $sql): void { /* ... */ }
}
class PostgreDB implements DB {
public function __construct() { echo "PostgreSQL DB 已建立\n"; }
public function connect(): void { /* ... */ }
public function exec(string $sql): void { /* ... */ }
}
class MssqlDB implements DB {
public function __construct() { echo "MSSQL DB 已建立\n"; }
public function connect(): void { /* ... */ }
public function exec(string $sql): void { /* ... */ }
}
// 簡單工廠(靜態工廠方法)
class DBFactory {
public static function create(string $type): DB {
$class = $type . 'DB';
if (!class_exists($class)) {
throw new InvalidArgumentException("不支援的資料庫類型: $type");
}
return new $class();
}
}
// 客戶端使用
$mysql = DBFactory::create('Mysql'); // 輸出: MySQL DB 已建立
$postgre = DBFactory::create('Postgre'); // 輸出: PostgreSQL DB 已建立
$mssql = DBFactory::create('Mssql'); // 輸出: MSSQL DB 已建立
DB 介面,而非具體類。