概念
用于通过复制现有的对象来创建新对象,而不是通过“new”关键字来直接实例化
简而言之,原型模式让我们能够在已有对象的基础上创建新对象。它依赖于“克隆”已有对象的状态,从而减少了重复构建相同对象的成本
应用场景
当某种对象需要经常赋值或只改变极小一部分的赋值,通过原型模式可以实现快速克隆,避免重复代码

基本结构

1)原型接口(Prototype):声明一个克隆自身的接口,具体原型类需要实现这个接口
2)具体原型类(ConcretePrototype):实现原型接口,定义如何复制自身的对象,要求深拷贝,避免与原对象冲突
3)客户端(Client):通过调用原型对象的克隆方法,来获取新的对象实例
代码实现
以“文档复制”为例
定义原型接口
定义一个统一的克隆方法 cloneDocument(),表示所有可复制的文档都应该实现这个接口,具备自我复制的能力
public interface DocumentPrototype extends Cloneable {
DocumentPrototype cloneDocument();
}
实现具体原型类
通过 Cloneable中的clone()方法创建副本,同时对引用对象进行深拷贝,防止多个副本见互相影响
@Data
public class WordDocument implements DocumentPrototype {
private String title;
private String content;
private List<String> images;
@Override
public DocumentPrototype cloneDocument() {
try {
WordDocument copy = (WordDocument) super.clone();
copy.images = new ArrayList<>(this.images); // 深拷贝,避免共享引用
return copy;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Clone failed", e);
}
}
public void show() {
System.out.println("Title: " + title);
System.out.println("Content: " + content);
System.out.println("Images: " + images);
}
public void addImage(String image) {
this.images.add(image);
}
}
客户端调用
客户端是需要通过对象调用克隆方法即可
public class Client {
public static void main(String[] args) {
// 原始对象
List<String> images = new ArrayList<>();
images.add("cover.png");
WordDocument template = new WordDocument("招聘简历模板", "请填写个人信息", images);
// 复制对象
WordDocument doc1 = (WordDocument) template.cloneDocument();
doc2.setTitle("xxx的简历");
doc2.setContent("xxx,x年的Java开发经验");
doc2.addImage("xxx_avatar.png");
}
}
优缺点
优点
1)提高性能:原型模式通过克隆已有的对象来创建新对象,省去了重新 new 的过程,尤其适合那种初始化过程比较复杂或者耗资源的对象
2)简化创建对象:对于创建逻辑非常复杂的对象,直接克隆更方便
缺点
1)深拷贝问题:若对象内部还有嵌套引用,比如有 List、Map 或其他复杂对象,需要手动实现深拷贝
