原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
原型模式中的角色:
- Prototype:抽象原型类,声明克隆方法的接口。
- ConcretePrototype:具体原型类,实现抽象原型类中声明的克隆方法。
原型模式的简单实现
(1) 具体原型类
Object 类充当抽象原型类,clone() 方法为原型方法。
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getTimeArea() {
return timeArea;
}
public void setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public Resume clone() {
Object obj = null;
try {
obj = super.clone();
return (Resume)obj;
} catch(CloneNotSupportedException e) {
System.out.println("不支持复制!");
return null;
}
}
}
(2) 客户端调用
public class Client {
public static void main(String[] args) {
Resume resume = new Resume();
resume.setName("yuzhiyi");
resume.setSex("男");
resume.setAge("23");
resume.setTimeArea("09:00");
resume.setCompany("BA");
System.out.println(resume.getName());
System.out.println(resume.getSex());
System.out.println(resume.getAge());
System.out.println(resume.getTimeArea());
System.out.println(resume.getCompany());
Resume newResume = resume.clone();
System.out.println(newResume.getName());
System.out.println(newResume.getSex());
System.out.println(newResume.getAge());
System.out.println(newResume.getTimeArea());
System.out.println(newResume.getCompany());
}
}
浅复制
浅复制:被复制对象的所有变量都含有原来的对象相同的值,而所有的对其他对象的应用都仍然指向原来的对象。
public class Attachment {
private String path;
public void setPath(String path) {
this.path = path;
}
public String getPath() {
return path;
}
public void download() {
System.out.println("下载文件" + path);
}
}
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
private Attachment attachment;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getTimeArea() {
return timeArea;
}
public void setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public Attachment getAttachment() {
return attachment;
}
public void setAttachment(Attachment attachment) {
this.attachment = attachment;
}
public Resume clone() {
Object obj = null;
try {
obj = super.clone();
return (Resume)obj;
} catch(CloneNotSupportedException e) {
System.out.println("不支持复制!");
return null;
}
}
}
public class Client {
public static void main(String[] args) {
Resume resume = new Resume();
Attachment attachment = new Attachment();
resume.setAttachment(attachment);
Resume newResume = resume.clone();
System.out.println(resume== newResume); // false
System.out.println(resume.getAttachment() == newResume.getAttachment()); // true
}
}
深克隆
深克隆:无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象
public class Attachment implements Serializable {
private static final long serialVersionUID = 6704368236366246076L;
private String path;
public void setPath(String path) {
this.path = path;
}
public String getPath() {
return path;
}
public void download() {
System.out.println("下载文件");
}
}
public class Resume implements Serializable {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
private Attachment attachment;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getTimeArea() {
return timeArea;
}
public void setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public Attachment getAttachment() {
return attachment;
}
public void setAttachment(Attachment attachment) {
this.attachment = attachment;
}
public Resume deepClone() throws IOException, ClassNotFoundException {
// 对象写入流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
// 对象从流中取出
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (Resume) objectInputStream.readObject();
}
}
public class Client {
public static void main(String[] args) {
Resume resume = new Resume();
Attachment attachment = new Attachment();
resume.setAttachment(attachment);
Resume newResume = null;
try {
newResume = resume.deepClone();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(resume== newResume); // false
System.out.println(resume.getAttachment() == newResume.getAttachment()); // false
}
}
网友评论