原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过标准的构造方法。这样做的目的是提高性能和避免构造函数的繁琐步骤。
原型模式的主要思想:
原型模式的核心思想是通过复制(克隆)现有的对象来创建新的对象。它主要包含两个角色:
- 原型类(Prototype): 定义了克隆方法,用于复制自身的实例。这个类必须实现
Cloneable接口,通常包含一个名为clone的方法。 - 具体原型类(ConcretePrototype): 实现了克隆方法,通过该方法可以复制自己。这个类是我们要创建复制的对象。
浅克隆和深度克隆:
-
浅克隆: 在浅克隆中,复制的对象和原始对象共享相同的引用,即对于对象内部的引用类型成员变量,只复制引用而不复制引用的对象。Java中的
Object类提供的clone方法是一种浅克隆。class Prototype implements Cloneable { int value; ReferenceType reference; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } -
深度克隆: 在深度克隆中,复制的对象和原始对象拥有相互独立的引用,即对于对象内部的引用类型成员变量,不仅复制引用,还复制引用的对象。实现深度克隆的方式有多种,包括手动实现、使用序列化和反序列化等。
class Prototype implements Cloneable { int value; ReferenceType reference; @Override protected Object clone() throws CloneNotSupportedException { Prototype clone = (Prototype) super.clone(); clone.reference = new ReferenceType(this.reference); // 深度复制引用类型 return clone; } }
序列化和反序列化实现深度克隆:
Java中,使用序列化和反序列化可以实现深度克隆。具体步骤是将对象写入字节流,然后从字节流中读取对象。这样可以确保对象及其引用对象都被完整地复制。
import java.io.*;
class ReferenceType implements Serializable {
// 类的定义
}
class Prototype implements Serializable {
int value;
ReferenceType reference;
public Prototype deepClone() throws IOException, ClassNotFoundException {
// 将对象写入字节流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 从字节流中读取对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Prototype) ois.readObject();
}
}
上述代码中,ReferenceType类需要实现Serializable接口,以确保其对象可以被序列化。然后,在Prototype类中,通过序列化和反序列化实现了深度克隆。这样,对象及其引用对象都会被完整地复制。
总体而言,原型模式是一种简单而灵活的创建型模式,通过复制现有对象来创建新对象,提高了对象创建的效率。浅克隆和深度克隆的选择取决于对象内部是否包含引用类型的成员变量以及对克隆粒度的需求。