PHP工厂模式具体指什么
在PHP面向对象编程(OOP)中,设计模式是解决特定问题的经典代码结构方案,工厂模式(Factory Pattern)是最常用、最基础的一种创建型设计模式,它主要目的是定义一个创建对象的接口,但让子类决定实例化哪一个类,将实例化逻辑从使用逻辑中解耦,提高代码的灵活性、可维护性和可扩展性。
工厂模式的核心思想:封装创建逻辑
在直接实例化对象时,代码通常与具体的类强耦合(如 $user = new User()
),如果需要更换类(如从 User
换成 VipUser
),或修改实例化过程(如添加依赖注入、参数校验),就需要修改所有调用处的代码,工厂模式通过“工厂”这一中间层,将对象的创建过程封装起来,外部只需调用工厂的创建方法,无需关心具体如何实例化。
工厂模式的分类与具体实现
工厂模式主要分为三类:简单工厂模式(非严格意义上的设计模式,但常作为工厂模式入门)、工厂方法模式(Factory Method Pattern)和抽象工厂模式(Abstract Factory Pattern),下面通过PHP代码分别说明。
简单工厂模式(Simple Factory)
核心:由一个工厂类负责创建所有产品类的实例,根据传入参数决定创建哪种对象。
场景:当需要创建的对象较少,且创建逻辑简单时适用。
代码示例:
假设有一个支付场景,支持Alipay
和WechatPay
两种支付方式:
// 支付接口 interface Payment { public function pay(float $amount): string; } // 支付宝支付实现 class Alipay implements Payment { public function pay(float $amount): string { return "支付宝支付成功,金额:{$amount}元"; } } // 微信支付实现 class WechatPay implements Payment { public function pay(float $amount): string { return "微信支付成功,金额:{$amount}元"; } } // 简单工厂类 class PaymentFactory { public static function create(string $type): Payment { switch ($type) { case 'alipay': return new Alipay(); case 'wechat': return new WechatPay(); default: throw new \InvalidArgumentException('不支持的支付方式'); } } } // 客户端调用 $alipay = PaymentFactory::create('alipay'); echo $alipay->pay(100); // 输出:支付宝支付成功,金额:100元 $wechat = PaymentFactory::create('wechat'); echo $wechat->pay(200); // 输出:微信支付成功,金额:200元
优点:客户端只需调用工厂方法,无需关心具体类名,创建逻辑集中管理。
缺点:工厂类违反了“单一职责原则”(如果新增支付方式,需修改工厂类代码),且扩展性较差。
工厂方法模式(Factory Method)
核心:定义一个创建对象的接口(抽象工厂类或接口),但让子类(具体工厂类)决定实例化哪个类,每个具体工厂只负责创建一个具体产品。
场景:当产品种类较多,且希望每个产品由独立的工厂创建时,避免简单工厂类的臃肿。
代码示例:基于上述支付场景,改造为工厂方法模式:
// 支付接口(产品接口) interface Payment { public function pay(float $amount): string; } // 具体产品类 class Alipay implements Payment { public function pay(float $amount): string { return "支付宝支付成功,金额:{$amount}元"; } } class WechatPay implements Payment { public function pay(float $amount): string { return "微信支付成功,金额:{$amount}元"; } } // 工厂接口(创建接口) interface PaymentFactory { public function createPayment(): Payment; } // 具体工厂类:支付宝工厂 class AlipayFactory implements PaymentFactory { public function createPayment(): Payment { return new Alipay(); } } // 具体工厂类:微信支付工厂 class WechatPayFactory implements PaymentFactory { public function createPayment(): Payment { return new WechatPay(); } } // 客户端调用 $alipayFactory = new AlipayFactory(); $alipay = $alipayFactory->createPayment(); echo $alipay->pay(100); // 输出:支付宝支付成功,金额:100元 $wechatFactory = new WechatPayFactory(); $wechat = $wechatFactory->createPayment(); echo $wechat->pay(200); // 输出:微信支付成功,金额:200元
优点:符合“开闭原则”(新增产品时,只需新增具体工厂和产品类,无需修改现有代码);每个工厂职责单一,扩展性强。
缺点:类的数量会增多(每增加一个产品,需同时增加一个工厂类),增加系统复杂度。
抽象工厂模式(Abstract Factory)
核心:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类,即一个工厂可以创建多个产品族(如支付+退款、订单+日志等)。
场景:当需要创建的产品是一个“产品族”(多个相互关联的产品),且客户端不希望依赖具体产品实现时。
代码示例:扩展支付场景,增加“退款”功能,形成“支付+退款”产品族:
// 支付接口(产品族1) interface Payment { public function pay(float $amount): string; } // 退款接口(产品族2) interface Refund { public function refund(float $amount): string; } // 具体产品:支付宝支付和退款 class AlipayPayment implements Payment { public function pay(float $amount): string { return "支付宝支付成功,金额:{$amount}元"; } } class AlipayRefund implements Refund { public function refund(float $amount): string { return "支付宝退款成功,金额:{$amount}元"; } } // 具体产品:微信支付和退款 class WechatPayment implements Payment { public function pay(float $amount): string { return "微信支付成功,金额:{$amount}元"; } } class WechatRefund implements Refund { public function refund(float $amount): string { return "微信退款成功,金额:{$amount}元"; } } // 抽象工厂接口 interface PaymentFactory { public function createPayment(): Payment; public function createRefund(): Refund; } // 具体工厂:支付宝工厂(创建支付+退款) class AlipayFactory implements PaymentFactory { public function createPayment(): Payment { return new AlipayPayment(); } public function createRefund(): Refund { return new AlipayRefund(); } } // 具体工厂:微信工厂(创建支付+退款) class WechatFactory implements PaymentFactory { public function createPayment(): Payment { return new WechatPayment(); } public function createRefund(): Refund { return new WechatRefund(); } } // 客户端调用 $alipayFactory = new AlipayFactory(); $alipayPayment = $alipayFactory->createPayment(); $alipayRefund = $alipayFactory->createRefund(); echo $alipayPayment->pay(100) . "\n"; // 输出:支付宝支付成功,金额:100元 echo $alipayRefund->refund(50); // 输出:支付宝退款成功,金额:50元
优点:确保创建的产品是相互关联的(如支付宝支付必然搭配支付宝退款),客户端无需依赖具体产品,只需依赖抽象工厂。
缺点:扩展产品族困难(如新增“银联”支付,需修改所有工厂类接口),符合“开闭原则”但扩展成本较高。
工厂模式的应用场景
- 对象创建逻辑复杂:如对象需要依赖其他对象、参数校验、初始化配置等,通过工厂封装后,客户端无需关心细节。
- 需要降低耦合度:如插件化架构,核心代码不依赖具体插件实现,而是通过工厂动态加载插件。
- 需要动态创建对象:如根据配置文件或用户选择,决定实例化哪个类(如多语言切换、数据库类型切换)。
- 统一管理对象创建:如单例模式结合工厂模式,确保全局只有一个实例。
工厂模式的优缺点
优点
- 解耦:将对象创建与使用分离,客户端无需依赖具体类,只需依赖抽象接口。
- 扩展性强:符合“开闭原则”,新增产品时无需修改现有代码(工厂方法模式、抽象工厂模式)。
- 复用性高:创建逻辑集中,可在多处复用,减少重复代码。
缺点
- 增加复杂度:简单工厂模式可能违反单一职责;工厂方法模式、抽象工厂模式会增加类数量。
- 过度设计风险:如果创建
还没有评论,来说两句吧...