跳转到内容

PHP工厂模式

来自代码酷

模板:Note

PHP工厂模式[编辑 | 编辑源代码]

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方式。该模式通过定义一个创建对象的接口或抽象类,让子类决定实例化哪一个类,从而实现对象的创建与使用解耦。

核心概念[编辑 | 编辑源代码]

工厂模式的核心思想是将对象的创建过程封装在一个专门的类(工厂类)中,客户端代码只需与工厂交互,无需关心对象的具体实现细节。这提高了代码的灵活性和可维护性。

主要类型[编辑 | 编辑源代码]

工厂模式分为三种常见形式:

  1. 简单工厂模式(静态工厂)
  2. 工厂方法模式
  3. 抽象工厂模式

以下重点介绍前两种最常用的形式。

简单工厂模式[编辑 | 编辑源代码]

最简单的一种实现,通过静态方法根据输入参数返回不同类的实例。

代码示例[编辑 | 编辑源代码]

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"

结构说明[编辑 | 编辑源代码]

classDiagram class Vehicle { <<interface>> +drive() } class Car { +drive() } class Bike { +drive() } class VehicleFactory { +create(type): Vehicle } Vehicle <|-- Car Vehicle <|-- Bike VehicleFactory --> Car VehicleFactory --> Bike

工厂方法模式[编辑 | 编辑源代码]

更灵活的变体,定义一个创建对象的接口,但让子类决定实例化哪个类。

代码示例[编辑 | 编辑源代码]

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"

结构说明[编辑 | 编辑源代码]

classDiagram class Logistics { <<abstract>> +createTransport()*: Transport +planDelivery() } class Transport { <<interface>> +deliver() } class RoadLogistics { +createTransport(): Transport } class SeaLogistics { +createTransport(): Transport } class Truck { +deliver() } class Ship { +deliver() } Logistics <|-- RoadLogistics Logistics <|-- SeaLogistics Logistics --> Transport Transport <|.. Truck Transport <|.. Ship RoadLogistics --> Truck SeaLogistics --> Ship

实际应用场景[编辑 | 编辑源代码]

  • 数据库连接器:根据配置创建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);

数学表达[编辑 | 编辑源代码]

工厂模式可以形式化为: {FactoryProductConcreteFactoryiConcreteProducti

其中满足: pProduct,fFactoryf.create()=p

优缺点[编辑 | 编辑源代码]

优点 缺点
解耦客户端和具体类 增加代码复杂度
便于扩展新产品类型 需要维护更多类
符合单一职责原则

最佳实践[编辑 | 编辑源代码]

  • 当对象创建逻辑复杂时使用
  • 优先选择工厂方法模式以获得更好扩展性
  • 结合依赖注入容器使用效果更佳

模板:Tip

扩展阅读[编辑 | 编辑源代码]

  • 对比抽象工厂模式(处理产品族创建)
  • 研究依赖注入与工厂的关系
  • 了解Laravel服务容器的实现原理