← 返回题目列表

原型模式的优缺点是什么?

高频 中等 第 5 / 25 题 更新于 2026/07/28
原型模式优缺点深拷贝对象创建设计模式

简化版

原型模式的优点是能复用已有对象状态,减少复杂初始化成本,客户端不需要知道构造细节,也便于运行时动态创建相似对象。缺点是深拷贝实现复杂,可变引用容易共享出错,复制规则维护成本高,业务唯一字段如果处理不好会产生严重问题。

详细版

主要优点:

  • 避免重复初始化复杂对象;
  • 创建大量相似对象更方便;
  • 客户端不依赖具体构造过程;
  • 可以运行时动态注册和复制模板;
  • 对象创建方式更灵活;
  • 配合注册表能管理多种模板。

主要缺点:

  • 深拷贝复杂;
  • 可变引用容易误共享;
  • 循环引用对象图难处理;
  • Cloneable 有历史包袱;
  • ID、时间、状态等字段复制规则容易出错;
  • 对象结构变更后复制逻辑也要维护。

原型模式适合复杂对象复制,不适合简单对象硬套。

完整版教学

一、优点:复用复杂初始化状态

如果一个对象初始化需要设置很多默认值:

默认样式
默认权限
默认组件
默认规则
默认参数

原型模式可以把这些默认状态提前准备好。

后续创建对象时复制模板,比每次从零初始化更方便。

二、优点:客户端更简单

没有原型模式时,客户端可能要知道很多构造细节。

用了原型模式后,客户端只需要:

Report report = reportTemplate.copy();
report.setTitle("销售日报");

复杂初始化被封装在原型对象里。

这能降低客户端和具体构造过程的耦合。

三、优点:支持运行时动态配置

原型对象可以在运行时注册:

registry.register("vip-user", vipUserTemplate);

甚至可以从配置文件或数据库加载模板。

这比写死构造逻辑更灵活,适合模板化系统、低代码平台、游戏配置系统。

四、缺点:深拷贝容易出错

原型模式最大的坑就是可变引用。

class Template {
    List<String> rules;
}

如果复制时只是浅拷贝,多个副本共享同一个 rules

一个副本改规则,其他副本也会变。

这种 bug 隐蔽且难排查。

五、缺点:业务字段复制规则复杂

不是所有字段都应该复制。

例如订单对象:

  • 商品明细可以复制;
  • 收货地址可能可以复制;
  • 订单号不能复制;
  • 支付状态不能复制;
  • 创建时间通常要重新生成。

如果机械复制,会出现重复订单号、错误状态、审计信息混乱等问题。

六、缺点:对象图越复杂维护越难

如果对象包含多层嵌套、双向引用、缓存字段、外部资源引用,复制规则会很复杂。

这时要考虑是否真的应该复制整个对象,或者改用:

  • 专门的模板 DTO;
  • 建造者模式;
  • 工厂方法;
  • 配置驱动生成;
  • 备忘录模式保存快照。

七、常见误区与追问

原型模式节省的是重复初始化,不保证复制本身便宜。若构造模板需加载1000条规则耗时200 ms,而复制已解析结构只需5 ms,收益明显;若对象仅有3个标量字段,维护复制契约反而更贵。对象图越复杂,深拷贝、身份字段和资源引用的风险越高。

检查维度判定依据
优势成立条件已有稳定模板且初始化昂贵
主要风险复制边界随字段演化而失真

心法:比较“从零构造成本”和“正确复制成本”,不要默认复制更快。

  • 误区:原型模式一定提升性能。 深拷贝大对象图可能比重新构造更慢,必须基准测试。
  • 追问:它为什么降低客户端复杂度? 客户端只需选择模板并复制,不必重复了解复杂初始化参数。
  • 误区:原型可以完全替代工厂。 工厂仍可负责选择和管理原型,二者经常组合。
  • 追问:最大维护成本是什么? 新增可变字段后若未更新复制逻辑,会产生隐蔽共享。
  • 追问:怎样控制副本内存成本? 共享可靠不可变部分,对可变大结构采用写时复制或按需复制。

八、加强记忆

原型模式的优点是复用模板状态、简化复杂对象创建;缺点是复制边界难处理,尤其是深拷贝、可变引用和业务唯一字段。用它前要确认对象确实复杂且相似,否则直接构造更简单。