PHP与设计模式: 工厂方法模式详解与实战
PHP与设计模式: 工厂方法模式详解与实战
1. 什么是工厂方法模式?
- 定义
工厂方法模式是简单工厂模式的改进版。它使用抽象工厂接口或基类来定义工厂方法,具体由子类实现,生成对应的产品实例。 - 特点
将对象的创建逻辑移到了子类中,满足开闭原则(对扩展开放,对修改关闭)。
客户端只依赖抽象工厂接口,完全不关心具体产品的创建过程。
2. 工厂方法模式的结构
工厂方法模式通常由以下部分组成:
- 抽象产品(Product):定义产品的通用接口。
- 具体产品(ConcreteProduct):实现具体的产品逻辑。
- 抽象工厂(Creator):定义工厂方法接口,通常是一个抽象类或接口。
- 具体工厂(ConcreteCreator):实现工厂方法,创建具体的产品实例。
- 客户端(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. 代码解析
核心实现
- 抽象产品(Product 接口):
○ 定义产品的公共方法 getDescription()。 - 具体产品(ProductA 和 ProductB):
○ 实现了 Product 接口,分别提供产品A和产品B的功能。 - 抽象工厂(Factory 抽象类):
○ 提供了抽象的工厂方法 createProduct()。 - 具体工厂(FactoryA 和 FactoryB):
○ 实现 createProduct() 方法,分别返回具体产品A或B的实例。 - 客户端代码:
○ 通过工厂接口调用 createProduct(),获取产品实例,客户端无需关心具体产品的创建细节。
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. 工厂方法模式与简单工厂模式的对比
模式 | 主要特点 | 适用场景 |
---|---|---|
简单工厂模式 | 使用一个工厂类创建所有产品,违反开闭原则 | 产品种类少,创建逻辑简单的场景 |
工厂方法模式 | 每种产品对应一个具体工厂,符合开闭原则 | 产品种类多,需要频繁扩展的场景 |