1.在软件系统中,有些对象的创建过程较为复杂,而且有时候需要频繁创建,原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的意图所在。
2.在原型模式结构中定义了一个抽象原型类,所有的Java类都继承自java.lang.Object,而Object类提供一个 clone() 方法,可以将一个Java对象复制一份。因此在Java中可以直接使用Object提供的clone()方法来实现对象的克隆,Java语言中的原型模式实现很简单。
3.能够实现克隆的Java类必须实现一个标识接口Cloneable,表示这个Java类支持复制。如果一个类没有实现这个接口但是调用了clone()方法,Java编译器将抛出一个CloneNotSupportedException异常。
4.通常情况下,一个类包含一些成员对象,在使用原型模式克隆对象时,根据其成员对象是否也克隆,原型模式可以分为两种形式:深克隆和浅克隆。
邮件浅克隆:
public class Email implements Cloneable
{
private Attachment attachment=null;
public Email()
{
this.attachment=new Attachment();
}
public Object clone()
{
Email clone=null;
try
{
clone=(Email)super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println("Clone failure!");
}
return clone;
}
public Attachment getAttachment()
{
return this.attachment;
}
public void display()
{
System.out.println("查看邮件");
}
}
public class Attachment
{
public void download()
{
System.out.println("下载附件");
}
}
public class Client
{
public static void main(String a[])
{
Email email,copyEmail;
email=new Email();
copyEmail=(Email)email.clone();
System.out.println("email==copyEmail?");
System.out.println(email==copyEmail);
System.out.println("email.getAttachment==copyEmail.getAttachment?");
System.out.println(email.getAttachment()==copyEmail.getAttachment());
}
}
潜克隆的原型和克隆出来的对象不是同一个对象,但是成员对象是同一个。结果如下:
email==copyEmail?
false
email.getAttachment==copyEmail.getAttachment?
true
邮件深克隆(实现Serializable接口):
package demo2;
import java.io.*;
public class Email implements Serializable
{
private Attachment attachment=null;
public Email()
{
this.attachment=new Attachment();
}
public Object deepClone() throws IOException, ClassNotFoundException, OptionalDataException
{
//将对象写入流中
ByteArrayOutputStream bao=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bao);
oos.writeObject(this);
//将对象从流中取出
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return(ois.readObject());
}
public Attachment getAttachment()
{
return this.attachment;
}
public void display()
{
System.out.println("查看邮件");
}
}
package demo2;
import java.io.*;
public class Attachment implements Serializable
{
public void download()
{
System.out.println("下载附件");
}
}
package demo2;
public class Client
{
public static void main(String a[])
{
Email email,copyEmail=null;
email=new Email();
try{
copyEmail=(Email)email.deepClone();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("email==copyEmail?");
System.out.println(email==copyEmail);
System.out.println("email.getAttachment==copyEmail.getAttachment?");
System.out.println(email.getAttachment()==copyEmail.getAttachment());
}
}
深克隆的原型的对象和成员对象与克隆后的都不是同一个
email==copyEmail?
false
email.getAttachment==copyEmail.getAttachment?
false