原型模式
原型模式通过复制已有对象来创建新对象,而不是每次都从零开始 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、自定义对象,必须认真考虑深拷贝策略。