Skip to content
Method约 1 分钟0 个小节更新于 2026/06/19在线编辑

原型模式

原型模式通过复制已有对象来创建新对象,而不是每次都从零开始 new

它适合对象创建成本高、初始化复杂,或者需要大量创建相似对象的场景。

解决什么问题

有些对象创建过程很重:

  • 需要读取配置。
  • 需要计算默认值。
  • 需要查询数据库。
  • 字段很多,大部分值都相同。

这时可以先准备一个“原型对象”,后续通过复制原型再修改少数字段。

text
原型对象
  -> clone
  -> 修改少量字段
  -> 得到新对象

浅拷贝和深拷贝

原型模式最重要的是理解拷贝深度。

浅拷贝

只复制对象本身,引用类型字段仍然指向同一个对象。

text
order1.items -> 同一个 List
order2.items -> 同一个 List

如果修改 order2.items,可能影响 order1.items

深拷贝

对象本身和内部引用对象都复制一份。

text
order1.items -> List A
order2.items -> List B

深拷贝更安全,但成本更高,也更容易写错。

Java 示例

java
import java.util.ArrayList;
import java.util.List;

public class OrderTemplate {
    private String source;
    private List<String> tags = new ArrayList<>();

    public OrderTemplate(String source, List<String> tags) {
        this.source = source;
        this.tags = tags;
    }

    public OrderTemplate copy() {
        return new OrderTemplate(this.source, new ArrayList<>(this.tags));
    }

    public void setSource(String source) {
        this.source = source;
    }

    public List<String> getTags() {
        return tags;
    }
}

使用:

java
import java.util.Arrays;

OrderTemplate base = new OrderTemplate("APP", Arrays.asList("normal", "paid"));
OrderTemplate copy = base.copy();
copy.setSource("MINI_PROGRAM");

这里 tags 使用了新的 ArrayList,避免两个对象共享同一个可变集合。

不建议直接依赖 Cloneable

Java 的 Cloneable 机制比较尴尬:

  • clone() 定义在 Object 中,不够直观。
  • 默认是浅拷贝。
  • 深拷贝需要自己处理引用字段。
  • 异常和访问权限都不够友好。

实际项目中,更推荐自己定义 copy() 方法,或者使用拷贝构造器。

java
public OrderTemplate(OrderTemplate source) {
    this.source = source.source;
    this.tags = new ArrayList<>(source.tags);
}

使用场景

  • 创建大量相似对象。
  • 对象初始化成本高。
  • 表单模板、规则模板、配置模板复制。
  • 游戏或图形系统中复制复杂对象。

优点

  • 避免重复初始化。
  • 创建相似对象更方便。
  • 可以在运行时复制对象状态。

缺点

  • 深拷贝复杂,容易遗漏引用字段。
  • 对象内部如果有文件、连接、线程等资源,不适合简单复制。
  • 可变对象共享引用时容易出现隐蔽 bug。

实战注意

原型模式不是简单地“复制对象”,而是要明确哪些字段可以共享,哪些字段必须独立。

如果对象里有集合、Map、自定义对象,必须认真考虑深拷贝策略。

以工程实践沉淀知识,以文档复盘成长。