新闻详情

新闻详情

首页 / 资讯中心 / 详情

DesignPatternsPHP 简单工厂模式(Simple Factory)源码实战指南:从实例化封装到与静态工厂的取舍

发布时间:2026/10/1 2:41:41来源:尧图网络
DesignPatternsPHP 简单工厂模式(Simple Factory)源码实战指南:从实例化封装到与静态工厂的取舍
示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载Simple Factory简单工厂是 PHP 中最轻量的创建型设计模式之一它用一个普通非静态类的方法集中负责对象的实例化逻辑让调用方与具体类解耦。本指南以 DesignPatternsPHP 仓库中 Creational/SimpleFactory 文档及其源码为主线结合 Bicycle 示例与同仓库的 StaticFactory 反例讲透简单工厂的实现方式、测试方法与选型依据。读完你将能够在本项目中直接运行该示例并在自己的代码里正确区分简单工厂与静态工厂的使用边界。一、模式定位简单工厂解决什么问题在软件工程中创建型模式Creational Patterns关注对象创建机制。最常见的问题创建方式是在业务代码里直接new具体类这会导致调用方与具体实现深度耦合——一旦产品类的构造参数或实现发生变化所有new的调用点都要跟着修改复杂度随之扩散。简单工厂的思路是把创建哪个对象的决定集中到一个工厂类的方法里。调用方只需要告诉工厂我要什么由工厂负责new出正确的实例。在 DesignPatternsPHP 项目中该模式被放在 Creational 分类下与 AbstractFactory、Builder、FactoryMethod、Prototype、StaticFactory 等模式并列属于创建型模式家族的一员。原文对它的定义非常精炼SimpleFactory is a simple factory pattern——它是最朴素的一类工厂一个类、一个或一组普通实例方法方法内部直接new并返回目标对象。二、核心差异为什么它不是静态工厂这是本文档最强调、也最容易被初学者忽略的一点。原文明确写道It differs from the static factory because it is not static. Therefore, you can have multiple factories, differently parameterized, you can subclass it and you can mock it. It always should be preferred over a static factory!简单工厂与静态工厂Static Factory的唯一本质区别在于方法是否为静态而这个区别带来了三点连锁优势能力简单工厂实例方法静态工厂static 方法实例化方式new SimpleFactory()后调用实例方法直接StaticFactory::factory(...)调用多个工厂实例✅ 可以创建多个、参数不同的工厂对象❌ 只有一个静态方法入口继承/子类化✅ 可以被继承覆盖❌final class通常直接封死测试替身Mock✅ 可被 PHPUnit 等框架 mock❌ 静态方法难以 mock即全局状态仓库中 StaticFactory.php 的源码注释从反面印证了这一点原文直接写道Note1: Remember, static means global state which is evil because it cant be mocked for testsNote2: Cannot be subclassed or mock-upped or have multiple different instances.而且静态工厂在仓库实现中被声明为final class并使用match表达式分发final class StaticFactory { public static function factory(string $type): Formatter { return match ($type) { number new FormatNumber(), string new FormatString(), default throw new InvalidArgumentException(Unknown format given), }; } }对比之下简单工厂天然规避了上述全部问题。这正是文档中It always should be preferred over a static factory!始终应该优先使用简单工厂而非静态工厂这句结论的底层依据——可测试性与可扩展性决定了它的优先级。三、源码剖析最小可运行的工厂实现本仓库的简单工厂示例共两个文件位于 Creational/SimpleFactory 目录。3.1 工厂类 SimpleFactory.php?php declare(strict_types1); namespace DesignPatterns\Creational\SimpleFactory; class SimpleFactory { public function createBicycle(): Bicycle { return new Bicycle(); } }实现要点declare(strict_types1);开启严格类型模式返回值声明: Bicycle保证了工厂契约的确定性方法createBicycle()是实例方法而非静态方法这是与 StaticFactory 的分水岭当前实现只负责new Bicycle()工厂的职责被收窄到单一产品、零参数——这是模式的最简形态。在实际业务中工厂方法可以接收参数并按条件返回不同产品例如createVehicle($type)届时工厂内部的分发逻辑如match/switch与 StaticFactory 的差异就仅剩静态与否这一点产品由工厂统一创建后调用方持有的类型是Bicycle将来替换为Bicycle的子类或重构为接口时只需要改工厂内部调用方代码不用动。3.2 产品类 Bicycle.php?php declare(strict_types1); namespace DesignPatterns\Creational\SimpleFactory; class Bicycle { public function driveTo(string $destination) { } }Bicycle是工厂生产的具体产品driveTo(string $destination)是它的行为方法示例中为空实现。产品类不依赖工厂工厂依赖产品——依赖方向保持单向符合创建型模式的基本职责划分。四、使用方式一行工厂、一路骑行原文给出了可直接运行的 Usage 示例$factory new SimpleFactory(); $bicycle $factory-createBicycle(); $bicycle-driveTo(Paris);拆解这三行代码new SimpleFactory()——实例化工厂。因为不是静态方法这里可以出现多个工厂实例每个实例可以持有不同的配置参数虽然本示例工厂无状态createBicycle()——向工厂请求产品得到Bicycle实例driveTo(Paris)——使用产品。调用方全程没有写过一个new Bicycle()创建细节被工厂封装。同样的调用模式在真实项目中可以演化为根据配置创建不同数据库连接、根据用户类型创建不同处理器等。工厂只暴露给我一个 X而不是告诉我怎么构造 X。五、测试验证工厂可以被 Mock 的证据仓库为简单工厂提供了 PHPUnit 测试见 Tests/SimpleFactoryTest.php?php declare(strict_types1); namespace DesignPatterns\Creational\SimpleFactory\Tests; use DesignPatterns\Creational\SimpleFactory\Bicycle; use DesignPatterns\Creational\SimpleFactory\SimpleFactory; use PHPUnit\Framework\TestCase; class SimpleFactoryTest extends TestCase { public function testCanCreateBicycle() { $bicycle (new SimpleFactory())-createBicycle(); $this-assertInstanceOf(Bicycle::class, $bicycle); } }该测试的验证逻辑为实例化SimpleFactory→ 调用createBicycle()→assertInstanceOf(Bicycle::class, ...)断言返回对象确为Bicycle类型。它同时验证了工厂方法的返回值契约与Bicycle的类型身份。在测试层面简单工厂相较静态工厂的核心优势得到体现SimpleFactory是一个普通类测试中可以直接new、可以直接注入、可以被 mock例如使用 PHPUnit 的createMock(SimpleFactory::class)来替换工厂行为而静态工厂的static方法无法被替换这正是文档与 StaticFactory 源码注释反复强调的静态即全局状态难以测试的痛点。运行方式项目根目录执行vendor/bin/phpunit Creational/SimpleFactory/Tests/SimpleFactoryTest.php项目基于 PHP 8.0见 composer.json开发依赖包含phpunit/phpunit: ^9先执行composer install安装依赖后即可运行上述测试。六、横向对比同仓库中的工厂模式家族将简单工厂放在 DesignPatternsPHP 的工厂家族中观察其边界更清晰模式关键特征仓库示例位置Simple Factory本文单个非静态方法创建产品可实例化、可继承、可 mockCreational/SimpleFactoryStatic Factory单个静态方法创建产品final class、不可 mockCreational/StaticFactoryFactory Method工厂方法由子类实现延迟到子类决定实例化哪个类Creational/FactoryMethodAbstract Factory通过接口创建一系列相关对象工厂本身抽象化Creational/AbstractFactory简单工厂是其中实现成本最低、最贴近直接new的一种当产品种类增多、创建逻辑需要参数化分发、或需要多个不同配置的工厂实例时在非静态 参数化 可继承这三个前提下简单工厂依然是首选必要时可平滑演进为工厂方法或抽象工厂。七、适用场景与使用建议适合使用简单工厂的场景创建逻辑简单但希望把new集中管理、便于统一替换产品实现需要多个不同配置的工厂实例或需要子类化工厂以扩展创建行为代码将被单元测试覆盖需要可 mock 的创建入口。不适合的场景产品族庞大、相互关联——此时应升级为 Abstract Factory创建过程复杂、需要子类决定具体类型——此时应使用 Factory Method你只是想写一个全局可调用的工具方法——请记住文档的告诫即使如此也优先使用非静态的简单工厂因为静态方法带来的全局状态与测试困难是长期维护成本。总结DesignPatternsPHP 的 SimpleFactory 示例虽然只有十余行代码却精准示范了创建型模式中最基础的一条原则——把创建从使用中剥离。createBicycle()的实例方法形态、assertInstanceOf的测试验证、以及 StaticFactory 源码注释中对静态方法的明确批评三者共同构成了简单工厂优于静态工厂这一结论的完整证据链。在你自己的项目中从一行new开始到引入简单工厂再到按需演进为工厂方法——这正是对象创建机制逐步走向健壮的自然路径。赞分享示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载相关推荐tsParticles Easing Quad 插件完全指南默认二次缓动函数的实现原理、版本演进与接入实战tsParticles Easing Quad 插件完全指南默认二次缓动函数的实现原理、版本演进与接入实战 导读 本文以 plugins/easings/qu示例工程教程CS-Notes 技术面试必备简单工厂模式Simple Factory原理、类图与 Java 代码实战CS Notes 技术面试必备简单工厂模式Simple Factory原理、类图与 Java 代码实战 简单工厂Simple Factory是创建型设知识库文档教程SlopeCraft终极指南如何将任何图片转化为Minecraft立体地图画SlopeCraft终极指南如何将任何图片转化为Minecraft立体地图画 你是否曾经在Minecraft中尝试创建精美的像素艺术却被繁琐的手动放置方块过桌面应用图像处理媒体生成上一篇显卡驱动残留清不净DDU 显卡驱动清理彻底卸载一次搞定下一篇还在复制召唤师名字查数据Seraphine 把战绩查询和自动 B/P 都替你干了创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Java基础自学路线图:从环境配置到面试通关的关键要点 2026/10/1 4:27:47

Java基础自学路线图:从环境配置到面试通关的关键要点

先说个现象:最近整理Java相关的热搜词,发现最靠前的不是某个炫酷框架,而是“java基础”、“java面试题”、“java自学路线图(超全超详细)”这类词。这让我挺有感触。我做了十几年Java,带过不少刚入行的新人…

阅读更多 →
不懂审美?游戏美术评价的三把尺子:风格、基本功与协作 2026/10/1 4:27:47

不懂审美?游戏美术评价的三把尺子:风格、基本功与协作

被美术同事当面甩一句“你不懂审美”,大概是很多策划和程序职业生涯里最窝火的一刻。入行头两年,我也经常被这句话噎得说不出话。但后来我逐渐想明白一件事:审美根本不是一种虚无缥缈的天赋,而是有一套可以被拆解、被学习、被验证…

阅读更多 →
ClickHouse备份与恢复全攻略:从物理快照到SQL命令的完整实践 2026/10/1 4:27:47

ClickHouse备份与恢复全攻略:从物理快照到SQL命令的完整实践

ClickHouse 的备份与恢复,一直是生产环境里最绕不开、也最容易踩坑的话题。我见过不少团队,数据量不大,但对备份的理解停留在“做了 mysqldump 就等于备份了”的阶段,结果真出故障时才发现,要么恢复时间长得离谱&#…

阅读更多 →
LeetCode高频题打家劫舍:动态规划核心套路与滚动数组优化详解 2026/10/1 4:27:47

LeetCode高频题打家劫舍:动态规划核心套路与滚动数组优化详解

打家劫舍这道题,是我在刷 LeetCode Hot100 时遇到的第 68 道题,也是刷题群里被问到最多的高频动态规划题。题目描述非常简单——一条街上每户人家有一定金额,相邻两家不能被同时偷,否则会触发警报,问你能偷到的最大金额…

阅读更多 →
Anaconda+VSCode+Jupyter Notebook 安装配置与虚拟环境实战指南 2026/10/1 4:27:46

Anaconda+VSCode+Jupyter Notebook 安装配置与虚拟环境实战指南

现在入坑还不晚:Anaconda VSCode Jupyter Notebook 安装及使用全记录我在帮不少朋友配 Python 环境时发现一个现象:很多人不是不会写代码,而是被“环境”卡住了。Anaconda、VSCode、Jupyter Notebook 这三样东西,单独拆开看都不…

阅读更多 →
基于Spring Boot的超市收银与进销存一体化系统设计与实践 2026/10/1 4:27:40

基于Spring Boot的超市收银与进销存一体化系统设计与实践

把“基于Java的超市收银管理系统”这个题目拿到手的时候,很多同学第一反应是“这不就是个增删改查吗”。我当时也是这样想的,但真做完一版基于Spring Boot的商超POS收银与进销存一体化平台之后,才意识到这个题目远不止商品表和订单表那么简单…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉