侧边栏壁纸
博主昵称
流苏小筑

步伐虽小,密而不止

PHP与设计模式: 工厂方法模式详解与实战

2022年02月15日 25阅读 0评论 0点赞

PHP设计模式: 工厂方法模式详解与实战

1. 什么是工厂方法模式?

  • 定义
    工厂方法模式是简单工厂模式的改进版。它使用抽象工厂接口或基类来定义工厂方法,具体由子类实现,生成对应的产品实例。
  • 特点
    将对象的创建逻辑移到了子类中,满足开闭原则(对扩展开放,对修改关闭)。
    客户端只依赖抽象工厂接口,完全不关心具体产品的创建过程。

2. 工厂方法模式的结构

工厂方法模式通常由以下部分组成:

  1. 抽象产品(Product):定义产品的通用接口。
  2. 具体产品(ConcreteProduct):实现具体的产品逻辑。
  3. 抽象工厂(Creator):定义工厂方法接口,通常是一个抽象类或接口。
  4. 具体工厂(ConcreteCreator):实现工厂方法,创建具体的产品实例。
  5. 客户端(Client):通过调用工厂接口创建产品对象,而无需直接实例化具体类。

3. 工厂方法模式的PHP实现

下面是一个完整的工厂方法模式实现:

<?php

// 抽象产品
interface Product {
    public function getDescription(): string;
}

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

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

// 抽象工厂
abstract class Factory {
    // 工厂方法
    abstract public function createProduct(): Product;
}

// 具体工厂A
class FactoryA extends Factory {
    public function createProduct(): Product {
        return new ProductA();
    }
}

// 具体工厂B
class FactoryB extends Factory {
    public function createProduct(): Product {
        return new ProductB();
    }
}

// 客户端代码
function clientCode(Factory $factory) {
    $product = $factory->createProduct();
    echo $product->getDescription() . PHP_EOL;
}

// 测试
clientCode(new FactoryA()); // 输出: This is Product A.
clientCode(new FactoryB()); // 输出: This is Product B.
?>

4. 代码解析

核心实现

  1. 抽象产品(Product 接口):
    ○ 定义产品的公共方法 getDescription()。
  2. 具体产品(ProductA 和 ProductB):
    ○ 实现了 Product 接口,分别提供产品A和产品B的功能。
  3. 抽象工厂(Factory 抽象类):
    ○ 提供了抽象的工厂方法 createProduct()。
  4. 具体工厂(FactoryA 和 FactoryB):
    ○ 实现 createProduct() 方法,分别返回具体产品A或B的实例。
  5. 客户端代码:
    ○ 通过工厂接口调用 createProduct(),获取产品实例,客户端无需关心具体产品的创建细节。

5. 工厂方法模式的优缺点

优点

  1. 遵循开闭原则:增加新产品时,只需新增具体产品类和对应工厂类,不需要修改现有代码。
  2. 解耦对象创建和使用:客户端通过工厂接口获取对象实例,而不依赖具体类名。
  3. 灵活性高:可以根据需求动态选择不同的工厂实现。
    缺点
  4. 增加系统复杂性:每个产品都需要对应的工厂类,增加了类的数量。
  5. 不适合简单场景:如果产品种类少且变化不频繁,使用简单工厂模式更合适。

6. 实际应用场景

工厂方法模式在以下场景中非常有用:
多数据库支持
支持不同类型的数据库连接(如MySQL、SQLite):

<?php

interface DatabaseConnection {
    public function connect(): string;
}

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

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

abstract class DatabaseFactory {
    abstract public function createConnection(): DatabaseConnection;
}

class MySQLFactory extends DatabaseFactory {
    public function createConnection(): DatabaseConnection {
        return new MySQLConnection();
    }
}

class SQLiteFactory extends DatabaseFactory {
    public function createConnection(): DatabaseConnection {
        return new SQLiteConnection();
    }
}

// 客户端代码
function connectToDatabase(DatabaseFactory $factory) {
    $connection = $factory->createConnection();
    echo $connection->connect() . PHP_EOL;
}

connectToDatabase(new MySQLFactory());
connectToDatabase(new SQLiteFactory());
?>

7. 工厂方法模式与简单工厂模式的对比

模式主要特点适用场景
简单工厂模式使用一个工厂类创建所有产品,违反开闭原则产品种类少,创建逻辑简单的场景
工厂方法模式每种产品对应一个具体工厂,符合开闭原则产品种类多,需要频繁扩展的场景
0

—— 评论区 ——

昵称
邮箱
网址
取消