news 2026/6/15 14:07:50

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/5 0:48:30

零基础学PCB设计:从软件安装到布线完整指南

从零开始设计你的第一块PCB&#xff1a;软件安装到布线实战全记录你有没有想过&#xff0c;那些手机、智能手表、无人机里精密的电路板&#xff0c;其实自己也能设计&#xff1f;别被“电子工程”四个字吓退。今天&#xff0c;我们就用最接地气的方式&#xff0c;带你从零开始完…

作者头像 李华
网站建设 2026/6/15 13:35:59

5分钟上手vnpy:从零构建量化交易回测系统

5分钟上手vnpy&#xff1a;从零构建量化交易回测系统 【免费下载链接】vnpy 基于Python的开源量化交易平台开发框架 项目地址: https://gitcode.com/vnpy/vnpy 你是否遇到过这些问题&#xff1f;&#x1f4a1; 想测试交易策略却不知从何开始面对复杂的量化框架感到无从…

作者头像 李华
网站建设 2026/5/14 15:57:39

PrivateGPT终极部署指南:三分钟搞定本地AI知识库

还在为复杂的AI环境配置头疼吗&#xff1f;PrivateGPT让你轻松搭建本地知识库系统&#xff0c;无需联网即可实现智能问答&#xff01;本文将带你从零开始&#xff0c;用最简单的方法在Windows、macOS或Linux系统上部署属于自己的AI助手。 【免费下载链接】private-gpt 项目地…

作者头像 李华
网站建设 2026/6/7 7:06:33

5分钟终极语音克隆指南:让AI开口说你的话

5分钟终极语音克隆指南&#xff1a;让AI开口说你的话 【免费下载链接】OpenVoice 项目是MyShell AI开源的即时语音克隆技术OpenVoice&#xff0c;旨在提供一种能够快速从少量语音样本中准确复制人类声音特征&#xff0c;并实现多种语言及语音风格转换的解决方案。 项目地址: …

作者头像 李华
网站建设 2026/6/12 14:51:42

Java JWT 完整教程:从入门到精通的安全令牌实践

Java JWT 完整教程&#xff1a;从入门到精通的安全令牌实践 【免费下载链接】java-jwt Java implementation of JSON Web Token (JWT) 项目地址: https://gitcode.com/gh_mirrors/ja/java-jwt 在现代微服务架构和Web应用开发中&#xff0c;Java JWT 已成为实现安全认证和…

作者头像 李华
网站建设 2026/6/15 12:15:13

Apache ShenYu深度重构:Redis集群缓存架构设计完全指南

Apache ShenYu深度重构&#xff1a;Redis集群缓存架构设计完全指南 【免费下载链接】shenyu Apache ShenYu is a Java native API Gateway for service proxy, protocol conversion and API governance. 项目地址: https://gitcode.com/gh_mirrors/shen/shenyu 在当今微…

作者头像 李华