PHP工厂模式实现方法及设计模式解析
IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《PHP工厂模式怎么实现?工厂设计模式详解》,聊聊,我们一起来看看吧!
工厂模式通过将对象创建集中管理,降低耦合并提升扩展性;简单工厂用静态方法创建不同产品,工厂方法让子类决定实例化哪个类,抽象工厂则创建一组相关产品;适用于对象创建逻辑复杂、需解耦或统一管理的场景,但需避免过度设计。

工厂模式在PHP中主要用于将对象的创建逻辑从使用对象的客户端代码中分离出来。它的核心思想是提供一个创建对象的方法或接口,但让子类决定实例化哪一个具体类。这能有效降低代码的耦合度,让系统在面对新对象类型时更易于扩展和维护。简单来说,就是把“new”操作集中管理起来,而不是让它散落在代码的各个角落。
解决方案
要在PHP中实现工厂模式,我们通常会从一个相对简单的“简单工厂”开始理解,因为它最直观。虽然它不是GoF(Gang of Four)定义的23种设计模式之一,但在实际开发中非常常见且实用。
我们以一个创建不同类型汽车的场景为例。
首先,定义一个产品接口,所有具体产品都将实现这个接口。这确保了所有产品都有一个共同的契约。
drive() . " (Type: " . $sportsCar->getType() . ")\n";
$familyCar = CarFactory::createCar('family');
echo $familyCar->drive() . " (Type: " . $familyCar->getType() . ")\n";
// 尝试创建不存在的类型
try {
$unknownCar = CarFactory::createCar('truck');
echo $unknownCar->drive() . "\n";
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage() . "\n";
}在这个例子中:
Car接口定义了所有汽车都应该具备的行为。SportsCar和FamilyCar是具体的汽车产品。CarFactory是工厂类,它有一个静态方法createCar,负责根据传入的类型字符串来实例化具体的汽车对象。客户端代码只需要知道CarFactory和它能创建的类型,而不需要关心SportsCar或FamilyCar是如何被new出来的。
工厂模式在哪些场景下能大显身手?
我个人觉得,当你发现代码里充斥着大量的 new ConcreteProduct(),并且这些 new 操作散落在各处时,就该考虑工厂模式了。它就像一个中央厨房,把做菜的活儿统一管理起来。
具体来说,工厂模式特别适合以下几种情况:
- 对象创建逻辑复杂或多变时: 比如一个对象在创建前需要进行一系列的配置、参数验证或者依赖注入。把这些复杂性封装在工厂里,客户端代码就显得非常简洁。
- 需要根据不同条件创建不同类型的对象时: 就像我们上面的汽车例子,根据传入的字符串类型决定创建哪种汽车。如果这些条件判断逻辑散布在各处,会非常难以维护。
- 希望解耦客户端代码与具体产品类时: 客户端只需要知道产品接口,而不需要知道具体实现了这个接口的是哪个类。这使得在不修改客户端代码的前提下,可以轻松地引入新的产品类型或更换现有产品的实现。
- 需要统一管理对象生命周期时: 工厂模式可以作为对象池、单例模式的入口,或者在创建对象时执行一些日志记录、性能监控等额外操作。
- 构建可扩展的框架或库时: 如果你的库允许用户自定义某些组件,但又需要统一的创建方式,工厂模式就能提供一个很好的扩展点。用户只需要实现你的产品接口,然后注册到你的工厂中,你的核心逻辑就能无缝地使用这些用户自定义的组件。
它本质上就是把“变化”封装起来,让核心业务逻辑更加稳定。当你发现某个 new 操作总是伴随着 if/else if/else 或 switch 语句来决定创建哪个具体对象时,工厂模式几乎就是呼之欲出了。
简单工厂、工厂方法与抽象工厂,它们到底有啥区别?
我刚开始学设计模式时,这几个“工厂”把我搞得晕头转向。后来才明白,它们就像是生产线的不同进化阶段,解决的问题复杂度和侧重点都不一样。
简单工厂 (Simple Factory)
- 概念: 这是最基础的工厂形式,我们上面给出的汽车工厂就是典型。一个工厂类,通常包含一个静态方法,根据传入的参数创建并返回不同类型的产品。
- 特点: 简单直观,容易实现。
- 缺点: 当增加新的产品类型时,你需要修改工厂类的
create方法(比如在switch语句中增加case),这违反了“开闭原则”(Open/Closed Principle),即对扩展开放,对修改关闭。它也通常不是GoF设计模式之一,更多被视为一种编程习惯。 - 适用场景: 产品种类不多,且不经常变化的小型项目。
工厂方法 (Factory Method)
概念: 这是GoF定义的一种创建型模式。它定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法把对象的创建延迟到子类。
特点: 每个具体产品都有一个对应的具体工厂。当需要添加新产品时,你只需要添加新的具体产品类和新的具体工厂类,而不需要修改现有代码,完全符合开闭原则。
结构:
- Product (产品接口/抽象类): 定义产品行为。
- ConcreteProduct (具体产品): 实现产品接口。
- Creator (创建者接口/抽象类): 声明工厂方法,该方法返回一个Product类型的对象。
- ConcreteCreator (具体创建者): 重写工厂方法,返回一个ConcreteProduct实例。
PHP示例(简化):
// Product 接口同上 // ConcreteProduct (SportsCar, FamilyCar) 同上 // Creator 抽象类 abstract class CarCreator { abstract public function createCar(): Car; // 工厂方法 } // ConcreteCreator A class SportsCarCreator extends CarCreator { public function createCar(): Car { return new SportsCar(); } } // ConcreteCreator B class FamilyCarCreator extends CarCreator { public function createCar(): Car { return new FamilyCar(); } } // 客户端使用 $sportsCarCreator = new SportsCarCreator(); $mySportsCar = $sportsCarCreator->createCar(); echo $mySportsCar->drive() . "\n"; $familyCarCreator = new FamilyCarCreator(); $myFamilyCar = $familyCarCreator->createCar(); echo $myFamilyCar->drive() . "\n";适用场景: 当一个类不知道它所必须创建的对象的类,或者一个类希望由其子类来指定它所创建的对象时。
抽象工厂 (Abstract Factory)
- 概念: 这也是GoF定义的一种创建型模式。它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。可以理解为“工厂的工厂”。
- 特点: 创建的是“产品族”,而不是单一产品。比如一个工厂可以同时生产A型汽车和A型发动机,另一个工厂可以生产B型汽车和B型发动机。
- 结构:
- AbstractFactory (抽象工厂): 声明创建抽象产品对象的操作接口。
- ConcreteFactory (具体工厂): 实现抽象工厂接口,负责创建具体产品对象。
- AbstractProduct (抽象产品): 声明一类产品对象的接口。
- ConcreteProduct (具体产品): 定义将由具体工厂创建的产品对象。
- 适用场景: 当系统需要独立于产品的创建、组合和表示时,或者系统需要处理多组相关产品时(例如,UI框架需要根据操作系统创建不同风格的按钮、文本框等)。
总结一下,简单工厂是“一个工厂生产多种产品”,工厂方法是“每种产品都有一个专属工厂”,而抽象工厂是“一个工厂生产一族相关产品”。它们各自应对不同复杂度的对象创建需求。
使用工厂模式时可能遇到的挑战和一些思考
说实话,刚接触工厂模式的时候,觉得它简直是银弹,什么都想用它来包一层。但用多了就会发现,它也不是万能的。有时候为了“模式”而模式,反而把代码搞得更复杂了。
- 过度设计(Over-engineering)的风险: 对于非常简单的对象创建,比如一个没有依赖、构造函数参数固定的对象,引入工厂模式反而会增加不必要的抽象层和类数量。杀鸡焉用牛刀,有时直接
new反而是最清晰、最简单的做法。 - 类爆炸问题: 尤其在工厂方法模式中,每增加一个具体产品,就需要增加一个具体工厂。如果产品类型非常多,会导致类的数量急剧膨胀,管理起来可能变得复杂。抽象工厂模式更是如此,它会带来更多的接口和实现类。
- 调试复杂性: 对象创建被抽象到工厂中,当出现问题时,你可能需要多跳几层才能找到真正的实例化逻辑,这在一定程度上增加了调试的难度。
- 与现代PHP框架的集成: 现代PHP框架(如Laravel, Symfony)普遍采用依赖注入(Dependency Injection, DI)容器来管理对象的创建和依赖关系。DI容器本身就提供了强大的工厂能力,它能自动解析依赖、管理单例、甚至可以定义复杂的创建逻辑(例如通过服务提供者或绑定闭包)。在很多情况下,直接使用框架的DI容器可能比手动实现工厂模式更高效、更灵活,也更符合框架的最佳实践。容器本质上就是一个高级的工厂,它帮你管理了对象创建的“who”、“when”和“how”。
- 维护成本: 简单工厂模式在添加新产品时需要修改工厂类,违反开闭原则。虽然工厂方法和抽象工厂解决了这个问题,但它们引入了更多的抽象和类,也带来了更高的学习和维护成本。
所以,在决定使用工厂模式之前,最好先评估一下当前项目的规模、复杂度和未来的扩展需求。如果只是临时性的简单创建,或者项目已经在使用成熟的DI容器,那么过度地引入工厂模式可能适得其反。设计模式是为了解决问题而存在的,而不是为了炫技或者盲目追随。找到一个平衡点,让代码既能保持清晰的逻辑,又能适应未来的变化,才是最重要的。
终于介绍完啦!小伙伴们,这篇关于《PHP工厂模式实现方法及设计模式解析》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!
腾讯VIP会员退款流程及政策解析
- 上一篇
- 腾讯VIP会员退款流程及政策解析
- 下一篇
- Win11忘记密码怎么解决?快速找回方法分享
-
- 文章 · php教程 | 43分钟前 | PHP · php-fpm · PHP OPcache opcache_reset validate_timestamps revalidate_freq opcache_invalidate
- OPcache 更新代码后仍命中旧脚本,该检查哪些配置
- 382浏览 收藏
-
- 文章 · php教程 | 7小时前 |
- PHP DateTimeImmutable 处理跨时区预约的正确方式
- 448浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP Session 锁为什么会阻塞并发请求,怎样缩短持锁时间
- 305浏览 收藏
-
- 文章 · php教程 | 1天前 | PHP ·
- PHP Attribute 做路由元数据:读取、缓存与冲突处理
- 413浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP 枚举承载业务状态时怎样避免数据库值漂移
- 135浏览 收藏
-
- 文章 · php教程 | 1天前 | 协程 · 异常处理 · php教程 · 异常恢复 PHP Fiber Fiber suspend Fiber resume Fiber throw 可暂停任务
- 用 Fiber 封装可暂停任务:启动、挂起与异常恢复
- 246浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP 8.5 迁移 PDO 驱动常量时要改哪些代码
- 162浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 379次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 450次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 458次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 402次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 230次使用
-
- PHP JSON_THROW_ON_ERROR 抛错后怎么保留原始字段位置
- 2026-09-09 501浏览
-
- PHP 8.5 array_last() 怎么处理空数组:从 null 结果到兼容旧版本的 Polyfill
- 2026-08-16 501浏览
-
- 宝塔配置Ruby环境:RVM+Nginx反代教程
- 2026-05-29 501浏览
-
- unset函数作用范围详解
- 2026-05-29 501浏览
-
- VS Code配置Xdebug教程:PHP调试技巧全解析
- 2026-05-13 501浏览

