news 2026/2/13 12:55:16

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/2/9 8:35:07

突破性能瓶颈:xsimd SIMD加速库完全实战指南

突破性能瓶颈&#xff1a;xsimd SIMD加速库完全实战指南 【免费下载链接】xsimd C wrappers for SIMD intrinsics and parallelized, optimized mathematical functions (SSE, AVX, AVX512, NEON, SVE)) 项目地址: https://gitcode.com/gh_mirrors/xs/xsimd 在现代计算密…

作者头像 李华
网站建设 2026/2/7 11:34:11

SSH连接超时?保持PyTorch后台训练进程不中断

SSH连接超时&#xff1f;保持PyTorch后台训练进程不中断 在深度学习项目中&#xff0c;你是否曾经历过这样的场景&#xff1a;深夜启动一个长达48小时的模型训练任务&#xff0c;满怀期待地合上笔记本&#xff0c;第二天却发现SSH连接断开、训练进程终止&#xff0c;一切努力付…

作者头像 李华
网站建设 2026/2/12 22:52:21

Linux下Miniconda-Python3.9安装PyTorch全流程详解

Linux下Miniconda-Python3.9安装PyTorch全流程详解 在现代AI开发中&#xff0c;一个稳定、可复现的环境几乎是项目成败的关键。你有没有遇到过这样的场景&#xff1a;代码在本地跑得好好的&#xff0c;一换到服务器就报错&#xff1f;或者同事拉下你的项目&#xff0c;却因为“…

作者头像 李华
网站建设 2026/2/10 9:53:28

ECCV2022-RIFE动漫优化终极指南:如何让动画视频流畅度翻倍

ECCV2022-RIFE动漫优化终极指南&#xff1a;如何让动画视频流畅度翻倍 【免费下载链接】ECCV2022-RIFE 项目地址: https://gitcode.com/gh_mirrors/eccv/ECCV2022-RIFE 还在为观看动漫时出现的卡顿和画面撕裂而烦恼吗&#xff1f;ECCV2022-RIFE项目最新推出的动漫优化版…

作者头像 李华
网站建设 2026/2/9 2:28:27

WSL导出导入实现PyTorch环境迁移

WSL导出导入实现PyTorch环境迁移 在深度学习项目开发中&#xff0c;最让人头疼的往往不是模型设计或训练调参&#xff0c;而是那个看似简单却频频出问题的环节——环境配置。你有没有经历过这样的场景&#xff1a;好不容易在一台机器上跑通了代码&#xff0c;换到另一台设备却因…

作者头像 李华