PHP 简单工厂模式详解与实战

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,通过一个工厂类来创建对象,而不直接在客户端代码中实例化对象。这样可以减少new()的操作,使客户端代码更加简洁。


1. 简单工厂模式简介

  • 定义:简单工厂模式通过一个工厂类,根据传入的参数动态创建并返回不同的对象实例。
  • 特点: 客户端无需直接实例化对象,减少了耦合。 工厂类负责对象的创建逻辑。 不符合严格的设计模式分类,有时被称为“非正式模式”。

2. 简单工厂模式的结构

简单工厂模式主要包括以下部分:

  1. 工厂类:提供创建对象的方法,根据参数返回不同的对象实例。
  2. 产品类:需要被实例化的具体类。
  3. 客户端:通过工厂类获取产品实例,而不关心具体的创建逻辑。

3. PHP 简单工厂模式实现

以下是简单工厂模式的完整实现代码:

<?php

// 定义产品接口
interface Product {
    public function getDescription();
}

// 具体产品类 A
class ProductA implements Product {
    public function getDescription() {
        return "This is Product A.";
    }
}

// 具体产品类 B
class ProductB implements Product {
    public function getDescription() {
        return "This is Product B.";
    }
}

// 工厂类
class SimpleFactory {
    public static function createProduct($type) {
        switch ($type) {
            case 'A':
                return new ProductA();
            case 'B':
                return new ProductB();
            default:
                throw new Exception("Invalid product type.");
        }
    }
}

// 客户端代码
try {
    $productA = SimpleFactory::createProduct('A');
    echo $productA->getDescription() . PHP_EOL; // 输出: This is Product A.

    $productB = SimpleFactory::createProduct('B');
    echo $productB->getDescription() . PHP_EOL; // 输出: This is Product B.

} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>

4. 代码解析

工厂类 (SimpleFactory):

提供静态方法 createProduct,根据传入的类型创建不同的产品实例。 将对象的创建逻辑集中到一个地方,便于管理和修改。 具体产品类 (ProductA 和 ProductB):

每个具体产品类实现了 Product 接口,定义了具体的行为。 客户端代码:

客户端通过调用工厂类方法创建对象,避免直接依赖具体类。


5. 简单工厂模式的优点

降低耦合:客户端代码不需要知道具体类名,只需依赖工厂类。 集中管理:对象创建逻辑集中在工厂类,便于修改和维护。 代码复用:减少重复的对象创建代码。

6. 简单工厂模式的缺点

工厂类复杂度增加:随着产品种类增多,工厂类的逻辑可能变得复杂。 违反开闭原则:新增产品时需要修改工厂类代码,不符合“对扩展开放,对修改关闭”的原则。 不易扩展:工厂类本身是静态的,难以支持更复杂的需求。

7. 实际应用场景

  1. 日志系统 根据需求返回不同的日志记录器(如文件日志、数据库日志、远程日志):
<?php

interface Logger {
    public function log($message);
}

class FileLogger implements Logger {
    public function log($message) {
        echo "Logging to file: $message" . PHP_EOL;
    }
}

class DatabaseLogger implements Logger {
    public function log($message) {
        echo "Logging to database: $message" . PHP_EOL;
    }
}

class LoggerFactory {
    public static function createLogger($type) {
        switch ($type) {
            case 'file':
                return new FileLogger();
            case 'database':
                return new DatabaseLogger();
            default:
                throw new Exception("Invalid logger type.");
        }
    }
}

// 使用示例
$logger = LoggerFactory::createLogger('file');
$logger->log("This is a log message.");
?>
  1. 数据库连接 根据数据库类型返回不同的连接对象(如 MySQL、PostgreSQL、SQLite):
<?php

class MySQLConnection {
    public function connect() {
        return "Connected to MySQL.";
    }
}

class SQLiteConnection {
    public function connect() {
        return "Connected to SQLite.";
    }
}

class DatabaseFactory {
    public static function createConnection($type) {
        switch ($type) {
            case 'mysql':
                return new MySQLConnection();
            case 'sqlite':
                return new SQLiteConnection();
            default:
                throw new Exception("Invalid database type.");
        }
    }
}

// 测试
$db = DatabaseFactory::createConnection('mysql');
echo $db->connect(); // 输出: Connected to MySQL.
?>

  1. 与其他工厂模式的区别 简单工厂模式:只有一个工厂类,创建的逻辑固定,适用于对象种类较少的场景。 工厂方法模式:每种产品对应一个工厂类,支持扩展新产品,符合开闭原则。 抽象工厂模式:为一组相关或依赖的产品提供创建方法,适用于复杂的产品族场景。