设计模式-原型模式,介绍原型模式,及代码实现。
简介
原型模式用于创建重复的对象,同时又能保证性能,原型模式属于创建型模式。
分类
原型模式创建对象,可分为浅复制、深复制。
本文代码参考大话设计模式,即用java实现原型模式。需求:求职季,需要大量复制简历,这些简历大部分内容相同,可能有的简历有微微改动。
浅复制
浅复制是指:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
代码实现
简历类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
public class Resume implements Cloneable, Serializable {
private static final long serialVersionUID = -4410449301166191440L;
private String name; private String gender; private int age;
private WorkExperience workExperience;
public Resume() { workExperience = new WorkExperience(); }
public void display() { System.out.println(this.getName() + " " + this.getGender() + " " + this.getAge() + "\n工作经历: " + this.getWorkExperience().getWorkDate() + " " + this.getWorkExperience().getWorkCompany()); }
@Override public Object clone() throws CloneNotSupportedException {
return super.clone(); }
public String getName() { return name; }
public Resume setName(String name) { this.name = name;
return this; }
public String getGender() { return gender; }
public Resume setGender(String gender) { this.gender = gender;
return this; }
public int getAge() { return age; }
public Resume setAge(int age) { this.age = age;
return this; }
public WorkExperience getWorkExperience() { return workExperience; }
public void setWorkExperience(String workDate, String workCompany) { workExperience.setWorkDate(workDate); workExperience.setWorkCompany(workCompany); } }
|
工作经历类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class WorkExperience implements Serializable {
private static final long serialVersionUID = 1L;
private String workDate; private String workCompany;
public String getWorkDate() { return workDate; }
public WorkExperience setWorkDate(String workDate) { this.workDate = workDate;
return this; }
public String getWorkCompany() { return workCompany; }
public WorkExperience setWorkCompany(String workCompany) { this.workCompany = workCompany;
return this; }
}
|
客户端类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public class PrototypeClient {
public static void main(String[] args) throws CloneNotSupportedException {
Resume a = new Resume(); a.setName("lusiqi").setGender("男 ").setAge(25); a.setWorkExperience("2016-2020, ", "XX公司");
Resume b = (Resume) a.clone(); b.setWorkExperience("2016-2020, ", "YY公司");
Resume c = (Resume) a.clone(); c.setWorkExperience("2016-2020, ", "ZZ公司");
System.out.println("**********浅度拷贝:"); a.display(); b.display(); c.display();
}
}
|
结果:
1 2 3 4 5 6 7
| **********浅度拷贝: lusiqi 男 25 工作经历: 2016-2020, ZZ公司 lusiqi 男 25 工作经历: 2016-2020, ZZ公司 lusiqi 男 25 工作经历: 2016-2020, ZZ公司
|
浅度拷贝只能复制值属性,引用属性都指向相同的对象。
深度复制
深度复制在复制对象的所有值变量的同时,也会把引用对象的变量值指向复制过来的新对象,而不是原有的被引用的对象。
代码用两种方式实现:
- 简历的引用属性也实现Cloneable接口,即在克隆简历对象的同时,也克隆简历对象的引用属性工作经历对象。从而完成深度复制。
- 通过对象序列化,将对象写入流内,从流内读出对象,实现深度拷贝。
代码实现
简历类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
public class Resume implements Cloneable, Serializable {
private static final long serialVersionUID = -4410449301166191440L;
private String name; private String gender; private int age;
private WorkExperience workExperience;
public Resume() { workExperience = new WorkExperience(); }
public Resume(WorkExperience workExperience) throws CloneNotSupportedException { this.workExperience = (WorkExperience)workExperience.clone(); }
public void display() { System.out.println(this.getName() + " " + this.getGender() + " " + this.getAge() + "\n工作经历: " + this.getWorkExperience().getWorkDate() + " " + this.getWorkExperience().getWorkCompany()); }
@Override public Object clone() throws CloneNotSupportedException {
Resume obj = new Resume(this.workExperience); obj.setAge(this.age); obj.setGender(this.gender); obj.setName(this.name);
return obj; }
public Object deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( bos.toByteArray())); return ois.readObject();
}
public String getName() { return name; }
public Resume setName(String name) { this.name = name;
return this; }
public String getGender() { return gender; }
public Resume setGender(String gender) { this.gender = gender;
return this; }
public int getAge() { return age; }
public Resume setAge(int age) { this.age = age;
return this; }
public WorkExperience getWorkExperience() { return workExperience; }
public void setWorkExperience(String workDate, String workCompany) { workExperience.setWorkDate(workDate); workExperience.setWorkCompany(workCompany); } }
|
工作经历类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
public class WorkExperience implements Cloneable,Serializable {
private static final long serialVersionUID = 1L;
private String workDate; private String workCompany;
public String getWorkDate() { return workDate; }
public WorkExperience setWorkDate(String workDate) { this.workDate = workDate;
return this; }
public String getWorkCompany() { return workCompany; }
public WorkExperience setWorkCompany(String workCompany) { this.workCompany = workCompany;
return this; }
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); }
}
|
客户端类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class PrototypeClient {
public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
Resume aResume = new Resume(); aResume.setName("lusiqi").setGender("男 ").setAge(25); aResume.setWorkExperience("2016-2020, ", "XX公司");
Resume bResume = (Resume) aResume.clone(); bResume.setWorkExperience("2016-2020, ", "YY公司");
Resume cResume = (Resume) aResume.clone(); cResume.setWorkExperience("2016-2020, ", "ZZ公司");
Resume dResume = (Resume) aResume.deepClone(); dResume.setWorkExperience("2016-2020, ", "DD公司");
aResume.display(); bResume.display(); cResume.display(); dResume.display();
}
}
|
结果:
1 2 3 4 5 6 7 8
| lusiqi 男 25 工作经历: 2016-2020, XX公司 lusiqi 男 25 工作经历: 2016-2020, YY公司 lusiqi 男 25 工作经历: 2016-2020, ZZ公司 lusiqi 男 25 工作经历: 2016-2020, DD公司
|
深度复制在复制对象的所有值变量的同时,也会把引用对象的变量值指向复制过来的新对象。