news 2026/6/10 1:20:10

PHP工厂模式 = 抽象工厂 = 简单工厂?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP工厂模式 = 抽象工厂 = 简单工厂?

PHP 中的“工厂模式” ≠ “抽象工厂” ≠ “简单工厂”
三者虽同属创建型设计模式,但抽象层级、适用场景、解决的问题截然不同。混淆它们,会导致过度设计抽象不足


一、核心意图:解决什么问题?

模式核心意图问题场景
简单工厂(Simple Factory)封装对象创建逻辑客户端不想直接new,但产品类型固定
工厂方法(Factory Method)将对象创建延迟到子类产品族单一,但创建逻辑需子类定制
抽象工厂(Abstract Factory)创建一系列相关/依赖对象产品族多维,需保证组合一致性

🔑关键区分

  • 简单工厂:1 个工厂,N 个产品;
  • 工厂方法:N 个工厂(子类),1 个产品线;
  • 抽象工厂:1 个工厂,N×M 个产品族。

二、结构对比:UML 精简版

1.简单工厂
+----------------+ | SimpleFactory | +----------------+ | + create(type) | +----------------+ | v +--------+--------+ | ProductA | ProductB | +------------------+
  • 特点
    • 无继承,工厂是普通类;
    • 违反开闭原则(新增产品需改工厂)。
2.工厂方法
+----------------+ +---------------------+ | Creator |<------| ConcreteCreatorA | +----------------+ +---------------------+ | + factoryMethod()| | + factoryMethod() | +----------------+ +---------------------+ | | v v +----------------+ +---------------------+ | Product |<------| ConcreteProductA | +----------------+ +---------------------+
  • 特点
    • Creator 定义接口,子类实现
    • 符合开闭原则(新增产品只需加子类)。
3.抽象工厂
+------------------+ +-----------------------+ | AbstractFactory |<------| ConcreteFactoryA | +------------------+ +-----------------------+ | + createProductA()| | + createProductA() | | + createProductB()| | + createProductB() | +------------------+ +-----------------------+ | | v v +------------------+ +-----------------------+ | AbstractProductA |<------| ConcreteProductA1 | | AbstractProductB |<------| ConcreteProductB1 | +------------------+ +-----------------------+
  • 特点
    • 工厂创建多个产品族
    • 保证产品组合一致性(如 Win 按钮 + Win 文本框)。

三、PHP 实现:代码即文档

1.简单工厂(适合产品稳定)
// 产品接口interfaceLogger{publicfunctionlog(string$message);}// 具体产品classFileLoggerimplementsLogger{publicfunctionlog(string$message){/* 写文件 */}}classDbLoggerimplementsLogger{publicfunctionlog(string$message){/* 写 DB */}}// 简单工厂classLoggerFactory{publicstaticfunctioncreate(string$type):Logger{returnmatch($type){'file'=>newFileLogger(),'db'=>newDbLogger(),default=>thrownewException('Invalid logger type'),};}}// 使用$logger=LoggerFactory::create('file');
  • 优点:简单直接;
  • 缺点:新增RedisLogger需改工厂。
2.工厂方法(适合创建逻辑多变)
// 抽象 CreatorabstractclassLoggerFactory{abstractpublicfunctioncreateLogger():Logger;publicfunctionlog(string$message){$this->createLogger()->log($message);}}// 具体 CreatorclassFileLoggerFactoryextendsLoggerFactory{publicfunctioncreateLogger():Logger{returnnewFileLogger();}}classDbLoggerFactoryextendsLoggerFactory{publicfunctioncreateLogger():Logger{returnnewDbLogger();}}// 使用$factory=newFileLoggerFactory();$factory->log('Hello');
  • 优点:符合开闭原则;
  • 缺点:类爆炸(每产品需 1 Creator + 1 Product)。
3.抽象工厂(适合产品族组合)
// 抽象产品族interfaceButton{publicfunctionrender();}interfaceCheckbox{publicfunctionrender();}// 具体产品族classWinButtonimplementsButton{publicfunctionrender(){echo"Win Button";}}classWinCheckboximplementsCheckbox{publicfunctionrender(){echo"Win Checkbox";}}classMacButtonimplementsButton{publicfunctionrender(){echo"Mac Button";}}classMacCheckboximplementsCheckbox{publicfunctionrender(){echo"Mac Checkbox";}}// 抽象工厂interfaceGUIFactory{publicfunctioncreateButton():Button;publicfunctioncreateCheckbox():Checkbox;}// 具体工厂classWinFactoryimplementsGUIFactory{publicfunctioncreateButton():Button{returnnewWinButton();}publicfunctioncreateCheckbox():Checkbox{returnnewWinCheckbox();}}classMacFactoryimplementsGUIFactory{publicfunctioncreateButton():Button{returnnewMacButton();}publicfunctioncreateCheckbox():Checkbox{returnnewMacCheckbox();}}// 使用$factory=newWinFactory();$button=$factory->createButton();$checkbox=$factory->createCheckbox();
  • 优点:保证产品族一致性;
  • 缺点:扩展产品族需改所有工厂。

四、适用场景:PHP 项目中的选择指南

场景推荐模式原因
日志驱动(File/DB/Redis)简单工厂产品类型固定,无需子类扩展
多环境配置(Dev/Staging/Prod)工厂方法每环境创建逻辑不同,需子类定制
UI 主题切换(Win/Mac/iOS)抽象工厂需保证按钮+文本框+下拉框风格一致
支付网关(Alipay/WeChat/PayPal)简单工厂 or 工厂方法若仅创建支付对象 → 简单工厂;若需创建支付+通知对象 → 抽象工厂

💡Laravel 中的实践

  • 简单工厂Cache::store('redis')
  • 工厂方法EventServiceProvidershouldDiscoverEvents()
  • 抽象工厂:极少直接使用,但服务容器(Service Container) 可替代其功能。

五、高危误区

🚫 误区 1:“抽象工厂是工厂方法的升级版”
  • 真相
    • 工厂方法解决“单产品创建”
    • 抽象工厂解决“多产品组合”
    • 二者解决不同维度问题
🚫 误区 2:“必须用工厂模式替代 new”
  • 真相
    • 简单场景直接new更清晰
    • 过度抽象增加理解成本
🚫 误区 3:“Laravel 服务容器 = 抽象工厂”
  • 真相
    • 服务容器是依赖注入容器
    • 可通过绑定实现工厂逻辑,但非模式本身

六、终极心法:模式是工具,不是教条

不要问“该用哪种工厂”,
而要问“当前问题需要什么抽象”

  • 简单问题 → 简单工厂
  • 创建逻辑多变 → 工厂方法
  • 产品族组合 → 抽象工厂

真正的工程能力,
不在“知道模式”,
而在“知道何时不用模式”

这,才是 PHP 程序员的设计智慧。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 1:43:05

Docker Run命令结合Miniconda镜像实现PyTorch环境隔离实战

Docker Run命令结合Miniconda镜像实现PyTorch环境隔离实战 在深度学习项目日益复杂的今天&#xff0c;一个常见的场景是&#xff1a;你刚复现完一篇论文所需的 PyTorch 1.12 环境&#xff0c;转头就要为新项目安装最新的 PyTorch 2.0 —— 结果前者直接崩溃。这种“依赖地狱”几…

作者头像 李华
网站建设 2026/6/9 1:31:27

Android安装器革命:告别传统限制的全新解决方案

还在为系统安装器的各种限制而烦恼吗&#xff1f;&#x1f914; 每次安装应用都要面对繁琐的步骤和不确定的结果&#xff1f;今天&#xff0c;让我们一同探索一个能够彻底改变你Android应用安装体验的强大工具。 【免费下载链接】InstallerX A modern and functional Android a…

作者头像 李华
网站建设 2026/6/9 0:30:32

如何快速掌握OpenGL:45个实例的完整学习指南

OpenGL是现代图形编程的必备技能&#xff0c;这个开源项目通过45个精心设计的实例&#xff0c;从基础概念到高级特效&#xff0c;提供了一套完整的OpenGL学习路径。无论你是图形编程初学者还是希望提升技能的开发者&#xff0c;这个项目都能帮助你快速掌握OpenGL核心技术。 【免…

作者头像 李华
网站建设 2026/6/9 1:23:15

如何查看Miniconda环境中已安装的PyTorch版本?

如何查看 Miniconda 环境中已安装的 PyTorch 版本&#xff1f; 在深度学习项目开发中&#xff0c;你是否曾遇到过这样的场景&#xff1a;运行一份来自 GitHub 的模型代码时&#xff0c;突然报错 AttributeError: module object has no attribute compile&#xff1f;一番排查后…

作者头像 李华
网站建设 2026/5/31 0:53:03

突破硬件限制:消费级GPU上的多模态模型轻量化实战

突破硬件限制&#xff1a;消费级GPU上的多模态模型轻量化实战 【免费下载链接】smol-vision 项目地址: https://ai.gitcode.com/hf_mirrors/merve/smol-vision 在AI技术蓬勃发展的当下&#xff0c;视觉语言模型正成为连接文本与视觉世界的关键桥梁。然而&#xff0c;传…

作者头像 李华
网站建设 2026/6/3 18:59:18

微电路可靠性工程:MIL-HDBK-217F Notice 2故障率预测模型深度解析

微电路可靠性工程&#xff1a;MIL-HDBK-217F Notice 2故障率预测模型深度解析 【免费下载链接】MIL-HDBK-217F-Notice2.pdf资源文件介绍分享 MIL-HDBK-217F-Notice2.pdf 资源文件介绍 项目地址: https://gitcode.com/Open-source-documentation-tutorial/7f1e5 在电子系…

作者头像 李华