原型模式适合哪些应用场景?
简化版
原型模式适合对象创建成本高、初始化复杂、对象大部分字段相同、需要基于模板快速生成对象的场景。典型例子包括文档模板、报表模板、游戏对象、低代码页面配置、复杂查询条件、对象快照和测试数据构造。
详细版
常见适用场景:
- 文档、报表、合同模板复制;
- 游戏角色、怪物、道具对象复制;
- 低代码平台页面组件模板;
- 初始化成本高的复杂对象;
- 大量相似对象批量创建;
- 测试数据基于基础样本修改;
- 对象快照和状态恢复;
- 图形编辑器复制图形元素;
- 工作流节点模板复制;
- 配置对象基于默认模板生成。
不适合的场景是对象很简单、字段很少、创建成本很低,直接 new 更清晰。
完整版教学
一、文档和报表模板
很多文档对象有大量默认配置:
- 页眉页脚;
- 字体样式;
- 默认章节;
- 权限配置;
- 导出格式;
- 水印规则。
每次从零初始化很麻烦。
可以先准备模板对象,需要新文档时复制模板,再修改标题和业务数据。
二、游戏对象创建
游戏中经常有大量相似对象:
- 同类型怪物;
- 同职业角色;
- 同类道具;
- 同款技能;
- 地图元素。
这些对象有共同基础属性,但又有少量差异。
用原型模式可以复制基础模板,再修改位置、等级、名称等字段。
三、图形编辑器复制元素
画图软件里复制一个图形元素时,新元素通常继承:
- 形状;
- 大小;
- 颜色;
- 边框;
- 阴影;
- 图层属性。
然后只改变坐标。
这就是非常自然的原型模式场景。
四、低代码和配置平台
低代码平台里,页面组件可能有复杂配置:
表单组件
表格组件
图表组件
审批节点
流程节点
用户拖一个组件到画布上,本质上就是从组件模板复制出一个实例。
模板保留默认配置,实例保存用户修改。
五、测试数据构造
测试代码里经常要构造大量相似对象:
User baseUser = TestUsers.normalUser();
User admin = baseUser.copy();
admin.setRole("ADMIN");
这种方式能减少重复构造,也能让测试意图更清晰。
六、对象快照和状态恢复
有些系统需要保存对象某一刻的状态。
例如:
- 编辑器撤销;
- 工作流回滚;
- 游戏存档;
- 配置变更前快照。
可以通过复制对象保存快照。但如果对象图复杂,更常用专门的快照对象或备忘录模式。
七、常见误区与追问
适用场景的共同点是“已有高价值初始状态”。图形编辑器复制1个含20项样式的组件、游戏克隆预加载资源的敌人、测试从标准夹具派生变体,都比重新逐项组装更自然。若副本需要与原型共享大量可变运行状态,原型反而会放大耦合。
| 检查维度 | 判定依据 |
|---|---|
| 适合 | 模板稳定、初始化复杂、副本频繁 |
| 不适合 | 对象简单或复制语义无法界定 |
心法:先问是否存在“可复用的成品模板”,再问能否安全复制。
- 误区:对象创建频繁就应该用原型。 只有复制比构造更便宜且语义清楚时才成立。
- 追问:测试数据为什么适合原型? 可从合法基线副本只改1个字段,减少无关构造噪声。
- 误区:缓存中的对象可以直接作为原型返回。 直接返回会让调用者修改缓存,应返回副本或不可变视图。
- 追问:游戏资源都要深拷贝吗? 纹理等不可变重资源通常共享,位置和生命值等运行状态独立。
- 追问:原型能用于对象快照吗? 可以,但快照还需明确一致性时点、存储成本和恢复规则。
八、加强记忆
原型模式适合“先有模板,再复制实例”的场景:文档模板、游戏对象、图形复制、低代码组件、测试数据和复杂配置都很典型。对象越复杂、默认值越多、相似对象越多,原型模式越有价值。