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

PHP 兩大核心設計模式:工廠模式與單例模式實現、組合應用、現代化寫法

     編輯:PHP 綜合知識

1. 工廠模式:解耦對象創建

核心:定義創建對象的接口,由子類/具體工廠決定實例化哪個類。降低調用者與具體類的耦合。

經典實現(計算器示例)

<?php
abstract class Operation {
    abstract public function getValue(float $a, float $b): float;
    public function getAttr(): int { return 1; }
}

class Add extends Operation {
    public function getValue(float $a, float $b): float { return $a + $b; }
}
class Sub extends Operation {
    public function getValue(float $a, float $b): float { return $a - $b; }
}

class Factory {
    public static function create(string $op): ?Operation {
        return match ($op) {
            '+' => new Add(),
            '-' => new Sub(),
            default => null,
        };
    }
}

// 使用
$op = Factory::create('-');
echo $op->getValue(3, 6); // -3

實戰場景:數據庫驅動工廠

<?php
interface Database {
    public function connect(array $config): void;
    public function query(string $sql): iterable;
}

class MySQLDatabase implements Database { /* ... */ }
class PgSQLDatabase implements Database { /* ... */ }
class SqliteDatabase implements Database { /* ... */ }

class DBFactory {
    public static function create(string $driver, array $config): Database {
        $instance = match ($driver) {
            'mysql' => new MySQLDatabase(),
            'pgsql' => new PgSQLDatabase(),
            'sqlite' => new SqliteDatabase(),
            default => throw new InvalidArgumentException("Unsupported driver: $driver"),
        };
        $instance->connect($config);
        return $instance;
    }
}

// 配置驅動
$db = DBFactory::create($_ENV['DB_DRIVER'], $_ENV['DB_CONFIG'] ?? []);

2. 單例模式:全局唯一實例

核心:構造方法私有、靜態實例屬性、靜態獲取方法、防止克隆/反序列化。

經典實現(數據庫連接)

<?php
class Database {
    private static ?self $instance = null;
    private PDO $pdo;

    private function __construct(array $config) {
        $dsn = "mysql:host={$config['host']};dbname={$config['dbname']};charset=utf8mb4";
        $this->pdo = new PDO($dsn, $config['user'], $config['pass'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }

    public static function getInstance(array $config = []): self {
        if (self::$instance === null) {
            if (empty($config)) throw new LogicException('首次調用需傳入配置');
            self::$instance = new self($config);
        }
        return self::$instance;
    }

    // 防止克隆
    private function __clone() {}
    // 防止反序列化
    public function __wakeup() {
        throw new Exception("不能反序列化單例");
    }

    public function getPDO(): PDO { return $this->pdo; }
}

// 使用
$db = Database::getInstance($config);
$stmt = $db->getPDO()->query('SELECT 1');

組合應用:工廠 + 單例 = 連接池雛形

<?php
class ConnectionPool {
    private static array $instances = [];

    public static function get(string $name, array $config): Database {
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = Database::getInstance($config); // 單例按名稱區分
        }
        return self::$instances[$name];
    }
}

// 主庫、從庫、不同業務庫
$master = ConnectionPool::get('master', $masterConfig);
$slave = ConnectionPool::get('slave', $slaveConfig);

現代化最佳實踐(PHP 8.1+)

  • 工廠:使用 match 表達式、readonly 類、interface 契約、依賴注入容器(如 PHP-DI、Symfony DI)管理工廠本身。
  • 單例:考慮**避免單例**,改用**依賴注入**管理生命周期(容器單例作用域)。單例引入全局狀態,難以測試、難以並發隔離、隱藏依賴。
  • 替代方案:服務容器 $container->get(Database::class) 由容器控制實例化策略(單例、原型、請求作用域)。
  • 屬性掛載:PHP 8 屬性 #[Singleton] 配合編譯時/運行時分析工具標記。

總結對比

模式核心目的關鍵代碼點現代建議
工廠解耦創建邏輯靜態創建方法、介面/抽象類廣泛使用,配合 DI 容器
單例保證全局唯一私有構造、靜態實例、防克隆**謹慎使用**,優先 DI 容器管理
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved