PHP工厂模式
外观
PHP工厂模式[编辑 | 编辑源代码]
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方式。该模式通过定义一个创建对象的接口或抽象类,让子类决定实例化哪一个类,从而实现对象的创建与使用解耦。
核心概念[编辑 | 编辑源代码]
工厂模式的核心思想是将对象的创建过程封装在一个专门的类(工厂类)中,客户端代码只需与工厂交互,无需关心对象的具体实现细节。这提高了代码的灵活性和可维护性。
主要类型[编辑 | 编辑源代码]
工厂模式分为三种常见形式:
- 简单工厂模式(静态工厂)
- 工厂方法模式
- 抽象工厂模式
以下重点介绍前两种最常用的形式。
简单工厂模式[编辑 | 编辑源代码]
最简单的一种实现,通过静态方法根据输入参数返回不同类的实例。
代码示例[编辑 | 编辑源代码]
interface Vehicle {
public function drive();
}
class Car implements Vehicle {
public function drive() {
return "Driving a car";
}
}
class Bike implements Vehicle {
public function drive() {
return "Riding a bike";
}
}
class VehicleFactory {
public static function create($type) {
return match(strtolower($type)) {
'car' => new Car(),
'bike' => new Bike(),
default => throw new InvalidArgumentException("Unknown vehicle type")
};
}
}
// 客户端代码
$vehicle = VehicleFactory::create('car');
echo $vehicle->drive(); // 输出: "Driving a car"
结构说明[编辑 | 编辑源代码]
工厂方法模式[编辑 | 编辑源代码]
更灵活的变体,定义一个创建对象的接口,但让子类决定实例化哪个类。
代码示例[编辑 | 编辑源代码]
abstract class Logistics {
abstract public function createTransport(): Transport;
public function planDelivery() {
$transport = $this->createTransport();
return $transport->deliver();
}
}
interface Transport {
public function deliver(): string;
}
class Truck implements Transport {
public function deliver() {
return "Delivering by land in a box";
}
}
class Ship implements Transport {
public function deliver() {
return "Delivering by sea in a container";
}
}
class RoadLogistics extends Logistics {
public function createTransport(): Transport {
return new Truck();
}
}
class SeaLogistics extends Logistics {
public function createTransport(): Transport {
return new Ship();
}
}
// 客户端代码
$logistics = new SeaLogistics();
echo $logistics->planDelivery(); // 输出: "Delivering by sea in a container"
结构说明[编辑 | 编辑源代码]
实际应用场景[编辑 | 编辑源代码]
- 数据库连接器:根据配置创建MySQL、PostgreSQL等不同数据库连接
- 支付网关:根据用户选择创建PayPal、Stripe等支付处理器
- UI组件库:跨平台渲染时创建对应操作系统的按钮/窗口
电商案例[编辑 | 编辑源代码]
class PaymentProcessorFactory {
public function create($gatewayType): PaymentGateway {
return match($gatewayType) {
'paypal' => new PayPalAdapter(),
'stripe' => new StripeAdapter(),
default => throw new InvalidArgumentException("Unsupported payment gateway")
};
}
}
$processor = (new PaymentProcessorFactory())->create('paypal');
$processor->charge(100.00);
数学表达[编辑 | 编辑源代码]
工厂模式可以形式化为:
其中满足:
优缺点[编辑 | 编辑源代码]
优点 | 缺点 |
---|---|
解耦客户端和具体类 | 增加代码复杂度 |
便于扩展新产品类型 | 需要维护更多类 |
符合单一职责原则 |
最佳实践[编辑 | 编辑源代码]
- 当对象创建逻辑复杂时使用
- 优先选择工厂方法模式以获得更好扩展性
- 结合依赖注入容器使用效果更佳
扩展阅读[编辑 | 编辑源代码]
- 对比抽象工厂模式(处理产品族创建)
- 研究依赖注入与工厂的关系
- 了解Laravel服务容器的实现原理