新闻详情

新闻详情

首页 / 资讯中心 / 详情

DesignPatternsPHP 原型模式(Prototype Pattern)实战:用克隆替代 new 提升 PHP 8 对象创建效率

发布时间:2026/10/1 2:14:18来源:尧图网络
DesignPatternsPHP 原型模式(Prototype Pattern)实战:用克隆替代 new 提升 PHP 8 对象创建效率
示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载导读原型模式Prototype是创建型设计模式之一核心思路是用克隆现有对象取代通过构造函数新建对象从而规避new Foo()在对象初始化上的高昂成本。本文以 DesignPatternsPHP 仓库中Creational/Prototype模块的完整实现为骨架讲解原型模式的抽象原型设计、PHP 8 中__clone()的克隆机制、单元测试验证方式并给出它在批量创建大量数据对象如通过 ORM 一次性写入百万行记录场景下的实用方案。读完本文你将掌握如何基于抽象原型类派生出不同分类的具体原型并通过clone关键字低成本批量产出带默认状态的实例。模式定位与目的在软件工程中创建型设计模式关注对象创建机制试图以更适合场景的方式来创建对象。常规的new Foo()方式在对象初始化逻辑复杂、构造开销大时可能带来设计问题或增加复杂度。原型模式的思路非常直接创建一个原型对象然后克隆它而不是每次都用标准方式重新走一遍构造流程。仓库中Creational/Prototype/README.rst对这一目的的描述是To avoid the cost of creating objects the standard way (new Foo()) and instead create a prototype and clone it.即用创建原型 克隆替代标准方式创建对象从而避免对象创建成本。Prototype属于 Creational创建型模式家族与 AbstractFactory、Builder、FactoryMethod、Pool、SimpleFactory、Singleton、StaticFactory 并列。典型适用场景批量数据写入原型模式最典型的应用场景是一次性产生大量结构相同、仅有少量字段差异的对象。原文档给出的示例是Large amounts of data (e.g. create 1,000,000 rows in a database at once via a ORM).即通过 ORM 一次性向数据库写入 1,000,000 行记录时如果逐行new实体对象构造逻辑会被反复执行而先创建一个原型实体再在循环中克隆并只修改差异字段可以显著降低初始化开销。批量导入、报表生成、模板消息发送等同构对象批量产出的场景均适用。模式结构UML 类图仓库为 Prototype 模式提供了对应的 UML 类图Creational/Prototype/uml/uml.png展示了本模块的核心结构从 UML 图可以看出BookPrototype为抽象原型类持有title、category两个字段并声明__clone()抽象方法BarBookPrototype与FooBookPrototype通过继承泛化关系实现该抽象原型各自定义默认分类并实现克隆逻辑——这正是 Prototype 模式定义抽象原型接口/基类由具体原型通过自克隆产出新对象的标准结构。源码实现逐层拆解1. 抽象原型BookPrototypeBookPrototype.php 定义了原型的抽象基类是整套实现的核心骨架?php declare(strict_types1); namespace DesignPatterns\Creational\Prototype; abstract class BookPrototype { protected string $title; protected string $category; abstract public function __clone(); final public function getTitle(): string { return $this-title; } final public function setTitle(string $title): void { $this-title $title; } }关键设计点抽象__clone()方法PHP 语言层面的克隆钩子子类必须实现。克隆一个对象时 PHP 会自动调用该方法可在此执行克隆后收尾逻辑如重置引用、重新生成唯一标识等。final修饰的访问器getTitle()/setTitle()被声明为final禁止子类覆写保证原型对外接口统一避免子类破坏基类约定的读写行为。declare(strict_types1)全仓库代码统一开启严格类型模式setTitle(string $title)会拒绝非字符串参数传入。命名空间DesignPatterns\Creational\Prototype与仓库其他模块的 PSR 风格命名空间一致。2. 具体原型FooBookPrototype 与 BarBookPrototype两个具体原型类分别以不同的默认分类值体现每个原型自带一组默认状态的思想FooBookPrototype.php?php declare(strict_types1); namespace DesignPatterns\Creational\Prototype; class FooBookPrototype extends BookPrototype { protected string $category Foo; public function __clone() { } }BarBookPrototype.php?php declare(strict_types1); namespace DesignPatterns\Creational\Prototype; class BarBookPrototype extends BookPrototype { protected string $category Bar; public function __clone() { } }设计要点每个具体原型在属性声明处直接给$category赋默认值Foo/Bar克隆出的新对象天然携带所属分类无需在每次克隆后重新设置。当前示例中__clone()为空实现是因为$title、$category均为标量字符串PHP 默认的浅拷贝已能满足需求__clone()的存在更多是为克隆后需要深拷贝引用属性、重置状态的复杂场景预留扩展点。克隆机制的底层原理浅拷贝与__clone()钩子PHP 的对象克隆遵循两条核心规则理解它们才能用好原型模式浅拷贝shallow copyclone $obj会创建一个新对象其属性值与原对象相同。标量属性如本示例的string直接复制值互不影响但若属性是对象引用克隆出的新对象与原对象会共享同一个内部对象。__clone()自动回调克隆完成后PHP 会在新对象上自动调用__clone()方法。如果原型持有引用类型属性通常需要在该方法里手动深拷贝例如$this-someObj clone $this-someObj;避免新对象与原对象共享可变状态。从源码结构看BookPrototype.php 将__clone()声明为抽象方法、并要求子类实现正是为了让每个具体原型显式声明克隆后如何处理自身状态这是本模块对 PHP 原生克隆机制的模式化封装。单元测试验证克隆产物的类型与行为仓库为原型模式提供了专门的测试 Tests/PrototypeTest.php用于验证克隆出的对象保持原型类型、且可独立设置标题?php declare(strict_types1); namespace DesignPatterns\Creational\Prototype\Tests; use DesignPatterns\Creational\Prototype\BarBookPrototype; use DesignPatterns\Creational\Prototype\FooBookPrototype; use PHPUnit\Framework\TestCase; class PrototypeTest extends TestCase { public function testCanGetFooBook() { $fooPrototype new FooBookPrototype(); $barPrototype new BarBookPrototype(); for ($i 0; $i 10; $i) { $book clone $fooPrototype; $book-setTitle(Foo Book No . $i); $this-assertInstanceOf(FooBookPrototype::class, $book); } for ($i 0; $i 5; $i) { $book clone $barPrototype; $book-setTitle(Bar Book No . $i); $this-assertInstanceOf(BarBookPrototype::class, $book); } } }测试揭示的实用价值一次原型、多次克隆FooBookPrototype与BarBookPrototype各只new一次随后在循环中反复clone。这正是原型模式只创建一次原型的精髓——若批量产出 1,000,000 个实体构造函数只执行 1 次而非 1,000,000 次。克隆对象类型不变通过assertInstanceOf断言每次克隆产物仍是FooBookPrototype/BarBookPrototype类型保证多态行为。克隆对象彼此独立每个克隆体都通过setTitle()设置各自唯一的标题如Foo Book No 0、Foo Book No 1...说明克隆产物是独立实例互不干扰。本地运行与测试验证本仓库基于 Composer 管理依赖见 composer.json要求 PHP 8.0php: 8.0开发依赖包含 PHPUnit^9并通过classmap自动加载Behavioral、Creational、Structural、More四个源码目录。安装与运行方式如下# 1. 安装依赖 composer install # 2. 运行全部模式的测试含 Prototype 的 PrototypeTest ./vendor/bin/phpunit也可只运行 Prototype 模块的测试./vendor/bin/phpunit Creational/Prototype/Tests/PrototypeTest.phpphpunit.xml.dist 中配置了测试套件会扫描Creational/*/Tests等目录下所有以Test.php结尾的测试文件执行后应看到testCanGetFooBook通过即证明原型克隆链路创建原型 → 克隆 → 设置差异字段 → 类型保持工作正常。此外仓库支持用 Docker 构建并浏览文档见 README.mddocker-compose up --build使用原型模式的注意事项浅拷贝陷阱原型若包含对象/数组等引用类型属性克隆后新对象会与原对象共享内部引用必须在__clone()中手动深拷贝否则批量修改可能意外污染所有克隆体。克隆成本判断只有当构造开销 克隆开销时才值得使用原型模式对于构造函数极简单的对象直接new反而更清晰无需引入克隆。默认状态设计原型对象应承载稳定的默认状态如本示例的$category每次克隆后只改差异字段如$title这才能体现批量生产的效率优势。与工厂的配合实践中常将原型注册表原型工厂与模式结合通过类别键直接取出对应原型再克隆避免调用方接触具体原型类。小结通过 DesignPatternsPHP 仓库的 Prototype 模块可以看到一个完整可运行的原型模式样板抽象原型 BookPrototype.php 定义规范与克隆钩子具体原型 FooBookPrototype.php 与 BarBookPrototype.php 固化默认分类测试 Tests/PrototypeTest.php 实证了一次原型、多次克隆、类型保持、实例独立的核心行为。当你的应用面临批量创建同构对象如 ORM 一次性写入海量记录的诉求时用原型克隆替代逐次new是把对象创建成本从每次全量构造降为一次构造 多次浅拷贝的务实选择。赞分享示例工程教程【免费下载链接】DesignPatternsPHPSample code for several design patterns in PHP 8.x项目地址https://gitcode.com/gh_mirrors/de/DesignPatternsPHP点击查看免费下载相关推荐Composio原型模式通过克隆创建新对象Composio原型模式通过克隆创建新对象 什么是原型模式 原型模式Prototype Pattern是一种创建型设计模式它允许通过复制现有对象来创建新人工智能AI Agent工具调用MCP 服务MCP Clients如何使用pybind11实现C与Python对象的高效克隆完整指南如何使用pybind11实现C与Python对象的高效克隆完整指南 pybind11是一个轻量级的C库它提供了C11与Python之间无缝的互操开发工具终极指南Day.js如何通过原型模式实现高效的对象克隆终极指南Day.js如何通过原型模式实现高效的对象克隆 Day.js作为一款2kB轻量级的日期时间库以其与Moment.js相同的现代API和 immuta前端上一篇Dots-TTS-MLX-INT8重新定义边缘设备上的高效语音合成下一篇CogVideoX深度解析10秒高质量视频生成的Transformer架构实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

防火墙源代码.zip解析:从解包到双网卡透明网关部署 2026/10/1 4:04:14

防火墙源代码.zip解析:从解包到双网卡透明网关部署

简介:基于费尔防火墙 1.0 的源代码压缩包是一份面向网络安全开发者、高校学生及防火墙技术爱好者的学习资料,旨在帮助读者从底层理解防火墙的包过滤、规则控制与异常行为处理逻辑。压缩包仅约529KB,内部包含核心源码、功能说明文档&#xff0…

阅读更多 →
AWTK Windows开发环境搭建教程:从零到运行第一个Demo 2026/10/1 4:04:08

AWTK Windows开发环境搭建教程:从零到运行第一个Demo

如果你搜到这个标题,大概率已经在用或准备评估AWTK这套跨平台GUI框架。AWTK全称Toolkit AnyWhere,是一套用C语言实现的开源GUI引擎,日常主要出现在工业控制、智能硬件、车载仪表这些领域,但从开发效率来说,最舒服的起步…

阅读更多 →
Flutter鸿蒙适配实战:MessagePack二进制序列化替代JSON的跨端通信改造 2026/10/1 4:04:08

Flutter鸿蒙适配实战:MessagePack二进制序列化替代JSON的跨端通信改造

1. 项目背景与核心问题拆解上周接到一个任务,把团队维护了两年的 Flutter 项目适配到鸿蒙 HarmonyOS 上。UI 层面、路由层面、状态管理层面都还好说,真正让人头疼的是我们内部自研的那套数据通信协议——它长年依赖 JSON 字符串在 Flutter 与原生侧之间来…

阅读更多 →
Creo参数化设计+3D打印:从模型到实物的全链路实战指南 2026/10/1 4:04:08

Creo参数化设计+3D打印:从模型到实物的全链路实战指南

1. 从Creo参数化到3D打印:为什么说这套组合拳值得All in我最早接触3D打印那会儿,用的还是网上随便下载的现成STL模型,顶多在切片软件里旋转缩放一下,根本谈不上"设计"。后来系统地啃Creo,才意识到一个问题&a…

阅读更多 →
SVM支持向量机从原理到Python实战:核函数、参数调优与工程落地 2026/10/1 4:04:08

SVM支持向量机从原理到Python实战:核函数、参数调优与工程落地

1. 为什么到现在还在学SVM:它到底解决了什么问题标题里写着“从原理到实战”,我实际跑下来发现,真正把SVM讲透又做成全流程的教程其实没那么多。很多文章要么推到数学推导就断更了,要么直接调库喊一句“RBF核效果最好”完事&#…

阅读更多 →
CPO-VMD参数自动寻优:告别变分模态分解的K与alpha玄学调参 2026/10/1 4:04:08

CPO-VMD参数自动寻优:告别变分模态分解的K与alpha玄学调参

简介:面向信号分解与参数寻优需求的 MATLAB 程序包,针对 VMD 模态数与惩罚因子难以确定的问题,基于 2024 年新提出的冠豪猪优化算法(CPO)自动寻优,以包络熵作为适应度函数,适合故障诊断、特征提…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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