1. 模式意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2. 模式定义
Client:客户类提出创建对象的请求;
Prototype:给出所有的具体类型所需的接口;
Concrete Prototype:被复制的对象,需要实现抽象原型所要求的接口;
3. 模式实现
3.1 Java中的原型方法
Java的所有类都是从java.lang.Object类继承而来的,而Object类提供protected Object clone()方法对对象进行复制,子类当然也可以把这个方法置换掉,提供满足自己需要的复制方法。
Java的接口Cloneable只起到一个作用,就是在运行时通知Java虚拟机可以安全地在这个类上使用clone()方法。参见下面的说明
A class implements the Cloneable
interface to indicate to the Object.clone()
method that it is legal for that method to make a field-for-field copy of instances of that class.
Invoking Object's clone method on an instance that does not implement the Cloneable
interface results in the exception CloneNotSupportedException
being thrown.
By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone()
for details on overriding this method.
Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.
clone()方法将对象复制一份并返还给调用者。一般而言,clone()方法满足以下的描述:
对任何的对象x,都有 x.clone() != x, 即克隆对象与原对象不是同一个对象
对任何的对象x, 都有x.clone().getClass() == x.getClass(),即对象的类型一眼
浅拷贝:只拷贝按值传递的数据,而不复制它所引用的对象,即所有的对其他对象的引用都仍然指向原来的对象
深拷贝:除了浅拷贝之外,还拷贝引用类型的数据,那些引用其他对象的变量将指向被复制过的新对象,而不是原来的那些被引用的对象。
利用序列化实现深拷贝:
把对象写到流里的过程是序列化(Serializaiton)过程,而把对象从流中读出来的过程叫做反序列化(Deserialization)过程。写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里。
在Java中深拷贝一个对象,常常可以先使对象实现Serialization接口,然后把对象写到一个流中,再从流里读回来,便可以重建对象:
public Object 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 ois.readObject();
}
3.2 C#中原型方法
C#中的MemberwiseClone()方法和ICloneable接口:
4. 模式应用