尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

DesignPatternsPHP 创建型设计模式全解析:8 种对象创建方案在 PHP 8.x 中的实现

DesignPatternsPHP 创建型设计模式全解析:8 种对象创建方案在 PHP 8.x 中的实现 示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载创建型设计模式Creational Design Patterns关注的是如何以恰当的方式创建对象。本指南以 DesignPatternsPHP 仓库的 Creational 目录 为骨架逐一剖析 AbstractFactory、Builder、FactoryMethod、Pool、Prototype、SimpleFactory、Singleton、StaticFactory 这 8 种模式的用途、适用场景与 PHP 8.x 源码实现。读完本文你将掌握每种模式的取舍逻辑与可运行的示例代码路径能够在真实项目中做出正确的对象创建方案选型。什么是创建型设计模式在软件工程中创建型设计模式是一类专门处理对象创建机制的设计模式其核心目标是以一种适合当前情境的方式创建对象原文定义见 Creational/README.rst。直接使用new Foo()这种最基本的对象创建形式往往会在设计中引入问题或额外复杂度例如客户端需要知道具体类名、需要手动组装依赖、需要重复执行昂贵的初始化等。创建型模式通过对对象创建过程施加控制来解决这些问题——将创建与使用解耦让创建过程可复用、可配置、可替换。DesignPatternsPHP 项目在Creational/目录下收录了 8 种主流创建型模式每个模式均包含说明文档README.rst、完整可运行的 PHP 源码、UML 图uml/uml.png以及配套的 PHPUnit 测试Tests/目录全部基于 PHP 8.x 语法编写使用了match表达式、readonly风格属性、类型声明等特性。下表给出整体速览模式核心思想关键源码位置测试位置AbstractFactory创建一系列相关/依赖对象不暴露具体类Creational/AbstractFactoryAbstractFactoryTest.phpBuilder分步构建复杂对象将构建过程与表示分离Creational/BuilderDirectorTest.phpFactoryMethod通过子类化工厂来定制对象的创建方式Creational/FactoryMethodFactoryMethodTest.phpPool复用一组预初始化对象避免频繁分配与销毁Creational/PoolPoolTest.phpPrototype通过克隆原型对象来创建新对象Creational/PrototypePrototypeTest.phpSimpleFactory用非静态工厂方法集中创建逻辑Creational/SimpleFactorySimpleFactoryTest.phpSingleton保证应用中仅存在一个实例Creational/SingletonSingletonTest.phpStaticFactory用单个静态方法创建所有对象类型Creational/StaticFactoryStaticFactoryTest.phpAbstractFactory无痛创建一系列相关对象目的抽象工厂Abstract Factory用于创建一系列相关或相互依赖的对象而不指定它们的具体类。通常这些被创建的类都实现同一个接口抽象工厂的客户端不关心这些对象是如何被创建的它只关心这些对象如何组合在一起使用原文见 Creational/AbstractFactory/README.rst。源码实现仓库中的示例围绕跨平台写文件展开不同操作系统需要不同风格的 CSV 与 JSON 写入器。首先是工厂接口声明了两个产品族的创建方法interface WriterFactory { public function createCsvWriter(): CsvWriter; public function createJsonWriter(): JsonWriter; }来源WriterFactory.php随后Unix 与 Windows 两个工厂分别实现该接口各自产出对应的产品实例class UnixWriterFactory implements WriterFactory { public function createCsvWriter(): CsvWriter { return new UnixCsvWriter(); } public function createJsonWriter(): JsonWriter { return new UnixJsonWriter(); } }来源UnixWriterFactory.phpWinWriterFactory.php结构相同产品侧共 6 个类接口CsvWriter/JsonWriter及其 Unix/Win 两种实现UnixCsvWriter.php、UnixJsonWriter.php、WinCsvWriter.php、WinJsonWriter.php。客户端代码只依赖WriterFactory接口切换平台时只需替换工厂实例产品代码零改动。AbstractFactory 模式的 UML 类图工厂接口、具体工厂与产品接口/实现之间的协作关系。Builder分步构建复杂对象目的Builder 是一个负责分步构建复杂对象部件的接口。原文还给出了三条设计建议见 Creational/Builder/README.rst如果 builder 对它构建的对象有更深入的了解该接口可以演化为带默认方法的抽象类即适配器式的默认实现如果对象存在复杂的继承树为 builder 建立同样复杂的继承树也是合理的实践中 builder 常配合**流式接口Fluent Interface**使用例如 PHPUnit 的 Mock Builder。源码实现仓库示例以造车/造卡车为场景核心参与者有三个1. Builder 接口——约定构建步骤interface Builder { public function createVehicle(): void; public function addWheel(): void; public function addEngine(): void; public function addDoors(): void; public function getVehicle(): Vehicle; }来源Builder.php2. Director导演——只依赖 Builder 接口编排构建流程不关心具体实现class Director { public function build(Builder $builder): Vehicle { $builder-createVehicle(); $builder-addDoors(); $builder-addEngine(); $builder-addWheel(); return $builder-getVehicle(); } }来源Director.php3. 具体 Builder——CarBuilder.php与TruckBuilder.php各自实现接口产出不同的Vehicle子类Parts/Vehicle.php、Parts/Car.php、Parts/Truck.php零件类包括 Parts/Engine.php、Parts/Wheel.php、Parts/Door.php。Director的注释明确指出可以注入多个 builder 来构建更复杂的对象这正是 Builder 的扩展点所在。FactoryMethod真正的设计模式目的工厂方法Factory Method相比 SimpleFactory 的优势在于你可以通过子类化工厂来实现不同的对象创建方式原文见 Creational/FactoryMethod/README.rst。对于简单场景这个抽象类可以只是一个接口。原文特别强调工厂方法是真正的设计模式因为它实现了依赖倒置原则Dependency Inversion Principle——即 SOLID 中的D——FactoryMethod 类依赖的是抽象而非具体类。这正是它与 SimpleFactory、StaticFactory 的本质区别。源码实现仓库示例是一个典型的日志器工厂。工厂接口只声明一个创建方法interface LoggerFactory { public function createLogger(): Logger; }来源LoggerFactory.phpStdoutLoggerFactory与FileLoggerFactory分别实现该接口返回各自日志实现Logger.php定义产品接口StdoutLogger.php与FileLogger.php为具体产品。客户端面向Logger与LoggerFactory两个抽象编程新增日志目标只需新增一对产品 工厂实现符合开闭原则。测试用例 FactoryMethodTest.php 验证了不同工厂产出不同日志类型的行为。Pool对象池与性能取舍目的对象池模式Object Pool维护一组已初始化、随时可用的对象即池而不是按需分配和销毁它们。客户端从池中申请对象使用完毕后将对象归还池中而不是销毁原文见 Creational/Pool/README.rst。适用场景与代价原文给出了清晰的适用判断标准Creational/Pool/README.rst对象池能带来显著性能提升的条件是类实例初始化成本高、实例化频率高、但同一时刻在用的实例数量少池化对象能以可预测的时间被获取而当新对象创建尤其是跨网络创建耗时不定时这一特性尤为重要这些收益主要适用于时间成本高的对象如数据库连接、Socket 连接、线程以及字体、位图等大型图形对象注意对于不持有外部资源、仅占用内存的简单对象单纯的对象池可能并不高效甚至降低性能——请勿滥用。源码实现仓库示例的 WorkerPool.php 实现Countable接口用两个数组分别维护占用中与空闲的工作者get()时若无空闲实例则新建、否则从空闲池弹出并用spl_object_hash()登记占用dispose()时将实例归还空闲池。产品对象 StringReverseWorker.php 是完成字符串反转的廉价工作者。测试 PoolTest.php 验证了申请—归还—再申请复用同一实例的行为。Prototype用克隆替代 new目的原型模式Prototype用于避免以标准方式new Foo()创建对象的成本转而创建一个原型并克隆它原文见 Creational/Prototype/README.rst。原文给出的典型例子是批量创建大量数据例如通过 ORM 一次性向数据库写入 1,000,000 行记录——此时反复执行构造流程的开销可以被克隆显著摊薄。源码实现BookPrototype.php 是一个抽象原型类持有$title与$category两个受保护属性并声明抽象方法__clone()这是 PHP 中定义克隆行为的标准钩子FooBookPrototype与BarBookPrototype两个具体原型在__clone()中赋予各自默认的类别值。测试 PrototypeTest.php 验证了克隆出的对象保持原型状态且类型正确。SimpleFactory 与 StaticFactory两个简化版工厂SimpleFactory可实例化、可子类化、可 mockSimple Factory 是最简单的工厂形态。原文明确给出了它与 Static Factory 的差异及强烈倾向性建议见 Creational/SimpleFactory/README.rst它不是静态的因此可以拥有多个参数不同的工厂实例、可以被子类化、可以被 mock 测试它总是应该优先于静态工厂被使用仓库实现 SimpleFactory.php 极简一个createBicycle()方法返回Bicycle实例。原文还给出了完整的使用示例$factory new SimpleFactory(); $bicycle $factory-createBicycle(); $bicycle-driveTo(Paris);原文见 Creational/SimpleFactory/README.rst产品类为 Bicycle.php测试见 SimpleFactoryTest.phpStaticFactory单一静态方法创建全部类型静态工厂Static Factory与抽象工厂类似用于创建一系列相关或依赖对象区别在于它仅用一个静态方法创建所有它能创建的对象类型该方法通常命名为factory或build原文见 Creational/StaticFactory/README.rst。仓库实现 StaticFactory.php 利用 PHP 8 的match表达式按类型分发同时其源码注释直白地提示了两条权衡StaticFactory.php静态即全局状态难以在测试中 mock无法被子类化、无法 mock、无法存在多个不同实例。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), }; } }产品侧为Formatter接口及其FormatString、FormatNumber两个实现Creational/StaticFactory测试见 StaticFactoryTest.php。Singleton被明确标注为反模式的模式目的与示例单例Singleton的目的很简单让应用中只有这一个对象实例来处理所有调用原文见 Creational/Singleton/README.rst。原文列举的典型应用场景包括数据库连接器、日志器、配置管理器、线程处理、应用锁文件文件系统中只能有一个等。重要警告反模式原文在文档开头就用大写加粗标注Creational/Singleton/README.rst这被认为是一个反模式为了更好的可测试性与可维护性请使用依赖注入Dependency Injection这是整个仓库中唯一被官方明确劝退的模式——因为全局单例状态会隐式耦合、难以替换、难以测试。作为替代仓库的 Structural/DependencyInjection 提供了推荐方案。源码实现与防御措施Singleton.php 展示了经典且防御完备的实现L11-L46懒加载private static ?Singleton $instance null;首次调用getInstance()时才创建实例私有构造private function __construct()禁止外部new禁止克隆私有__clone()防止克隆出第二个实例禁止反序列化__wakeup()直接抛出Exception(Cannot unserialize singleton)。这些防御措施加上final class修饰从构造、克隆、反序列化三个入口堵死了多实例的可能。测试 SingletonTest.php 断言两次getInstance()返回同一实例。四类工厂的选型对比与决策建议理解创建型模式的关键在于分清这组看起来很像的工厂模式之间的边界维度SimpleFactoryStaticFactoryFactoryMethodAbstractFactory创建入口实例方法静态方法接口方法子类定制接口方法产品族可子类化/可 mock✅❌✅✅依赖倒置依赖抽象部分部分✅官方认定为真模式✅输出对象单类多类一个方法分发单类多实现一系列相关类仓库官方倾向优先于 StaticFactory尽量回避推荐面向产品族决策建议可归纳为能用实例工厂就不用静态工厂——这是 SimpleFactory 文档中的明文结论需要可扩展、可定制创建逻辑时升级为 FactoryMethod让子类决定创建什么需要保证一整套相互配套的对象如跨平台写入器时选用 AbstractFactory需要控制对象生命周期与复用昂贵资源时考虑 Pool需要低成本批量生成对象时考虑 Prototype 克隆Singleton 尽量用依赖注入替代仅在确有全局唯一资源诉求且接受其测试代价时使用。如何查看、运行与验证仓库为每个模式都配套了 PHPUnit 测试可直接运行验证项目依赖见 composer.json测试配置见 phpunit.xml.dist# 安装依赖后运行全部创建型模式测试 composer install vendor/bin/phpunit Creational也可以针对单个模式运行例如vendor/bin/phpunit Creational/AbstractFactory/Tests/AbstractFactoryTest.php每个模式的README.rst中还通过literalinclude指令内嵌了全部源码如 Creational/AbstractFactory/README.rst无需打开源码文件即可在文档中通读完整实现顶层 Behavioral/README.rst 与 Structural/README.rst 则分别收录了行为型与结构型模式可与本文的创建型模式形成完整对照。总结创建型设计模式解决的是软件工程中最基础也最容易被忽视的问题——对象从何而来、如何而来。DesignPatternsPHP 的Creational/目录用 8 个短小精悍的 PHP 8.x 示例把控制对象创建这一思想落地成了可读、可测、可复用的代码从最朴素的 SimpleFactory到强调依赖倒置的 FactoryMethod再到面向产品族的 AbstractFactory以及另辟蹊径的 Pool、Prototype最后是被官方标注为反模式的 Singleton。理解这些模式各自的适用场景与代价你就能在真实项目中为每一次对象创建做出有依据、可维护的选择。赞分享示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载相关推荐DesignPatternsPHP 抽象工厂模式Abstract Factory实战指南用 WriterFactory 在 PHP 8.x 中按平台创建系列相关对象DesignPatternsPHP 抽象工厂模式Abstract Factory实战指南用 WriterFactory 在 PHP 8.x 中按平台创建系示例工程教程DesignPatternsPHP 结构型设计模式实战指南PHP 8.x 下的 11 种实体关系实现方案DesignPatternsPHP 结构型设计模式实战指南PHP 8.x 下的 11 种实体关系实现方案 本指南以仓库 Structural/ 目录为核心系示例工程教程深入解析 DesignPatternsPHP 中的行为型设计模式13 种模式的 PHP 8 实现指南深入解析 DesignPatternsPHP 中的行为型设计模式13 种模式的 PHP 8 实现指南 导读 本文围绕开源仓库 DesignPatternsPH示例工程教程上一篇Steam成就管理器终极指南快速解决游戏成就问题的完整方案下一篇3分钟快速上手Unity游戏去马赛克终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表