源码实战指南:从实例化封装到与静态工厂的取舍)
示例工程教程【免费下载链接】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),仅供参考