首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 工廠模式深度解析:解耦創建邏輯,應對業務變更的利器

     編輯:PHP 相關知識

為什麼需要工廠模式?

直接 new User('小明', 19) 看似簡單,但當類構造函數參數變更(如新增 $group 字段)時,所有調用處都需修改。若該類在項目中被實例化數十上百次,維護成本極高。工廠模式將「如何創建對象」封裝隔離,實現 創建邏輯與業務邏輯解耦。

從痛點到重構:演示演進

階段一:直接實例化(脆弱)

interface IUser {
    public function getName();
    public function getAge();
}

class User implements IUser {
    protected $_name;
    protected $_age;

    public function __construct(string $name, int $age) {
        $this->_name = $name;
        $this->_age  = $age;
    }
    public function getName(): string { return $this->_name; }
    public function getAge(): int     { return $this->_age; }
}

// 調用處
$u = new User('小明', 19);  // 當需新增 $group 時,所有 new 處必須改

階段二:構造函數默認值(治標不治本)

public function __construct(string $name, int $age, string $group = '默認組') { ... }
// 雖不報錯,但隱性依賴默認值,業務語義模糊,違反「顯式優於隱式」

階段三:工廠類封裝創建邏輯(推薦)

class UserFactory {
    /** 參數配置集中管理,可遷移至配置文件/數據庫 */
    private static $presets = [
        0 => ['name' => '小明', 'age' => 19, 'group' => '學生'],
        1 => ['name' => '小王', 'age' => 19, 'group' => '學生'],
        // 更多預設...
    ];

    public static function create(int $id): IUser {
        if (!isset(self::$presets[$id])) {
            throw new InvalidArgumentException("未知用戶預設 ID: $id");
        }
        $data = self::$presets[$id];
        return new User($data['name'], $data['age'], $data['group']);
    }
}

// 業務調用極簡
$user = UserFactory::create(0);
echo $user->getName();  // 小明

工廠模式核心優勢

維度直接 new工廠模式
參數變更影響面全項目掃描修改僅修改工廠類
創建邏輯複用不可複用集中管理,可擴展策略
測試友好度難以 Mock可注入 Mock Factory
配置外部化代碼硬編碼支援 JSON/YAML/DB 動態加載
單一職責原則業務邏輯混雜創建細節創建職責獨立

進階變體:參數化工廠

當預設不足以覆蓋所有場景,支援動態參數覆蓋:

public static function create(int $id, array $override = []): IUser {
    $data = array_merge(self::$presets[$id] ?? [], $override);
    return new User($data['name'], $data['age'], $data['group']);
}

// 用法
$teacher = UserFactory::create(0, ['group' => '教師', 'age' => 35]);

最佳實踐建議

  1. 接口優先:工廠返回接口類型(IUser),而非具體實現,便於後續替換實現類。
  2. 配置外部化:預設數據遷移至 config/users.php、Redis 或 DB,實現無發布變更參數。
  3. 異常處理:無效 ID 拋出具體異常,避免返回 null 導致下游報錯。
  4. 單例 vs 靜態:無狀態工廠用靜態方法;需持有連接池、緩存等狀態時改單例模式。
  5. 不要濫用:構造函數穩定、參數少、調用處少的類,直接 new 更簡潔。

總結

工廠模式不是為了「炫技」,而是為了將變化隔離在單一位置。當類的創建邏輯涉及參數組裝、依賴注入、配置讀取、策略選擇等復雜度時,引入工廠類是性價比最高的重構手段。從 new User(...) 到 UserFactory::create(...),代碼行數微增,維護性質變。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved