1.你一定写过如下的代码:
/**
* @author dxy
* @version 1.0
* @date 2021/10/24 9:22
* @decripton 简历
* @mail victorydeng@163.com
*/
@Data
public class Resume {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
public Resume(String name) {
this.name = name;
}
//设置个人信息
public void setPersonalInfo(String age, String sex) {
this.sex = sex;
this.age = age;
}
//设置工作经历
public void setWorkExperience(String timeArea, String company) {
this.timeArea = timeArea;
this.company = company;
}
public void display() {
System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
System.out.println(String.format("工作经历:%s,%s", timeArea, company));
}
}
public class Test {
public static void main(String[] args) {
Resume resumeA = new Resume("张无忌");
resumeA.setPersonalInfo("18","男");
resumeA.setWorkExperience("533-537","武当派");
Resume resumeB = new Resume("周芷若");
resumeB.setPersonalInfo("25","女");
resumeB.setWorkExperience("555-559", "峨眉派");
Resume resumeC = new Resume("赵敏");
resumeC.setPersonalInfo("23","女");
resumeC.setWorkExperience("554-558", "王府");
resumeA.display();
resumeB.display();
resumeC.display();
}
}
如果需要创建很多个对象,而且这些对象都差不多时,我们可以使用原型模式来帮我们简化。
2.原型模式
类图
多份简历的例子:
对于java而言,只要实现Cloneable接口就可以实现基于浅表复制的原型模式
修改代码:
@Data
public class Resume implements Cloneable {
private String name;
private String sex;
@Override
protected Resume clone() throws CloneNotSupportedException {
return (Resume)super.clone();
}
private String age;
private String timeArea;
private String company;
public Resume(String name) {
this.name = name;
}
//设置个人信息
public void setPersonalInfo(String age, String sex) {
this.sex = sex;
this.age = age;
}
//设置工作经历
public void setWorkExperience(String timeArea, String company) {
this.timeArea = timeArea;
this.company = company;
}
public void display() {
System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
System.out.println(String.format("工作经历:%s,%s", timeArea, company));
}
}
测试:
public static void main(String[] args) throws CloneNotSupportedException {
Resume resumeA = new Resume("张无忌");
resumeA.setPersonalInfo("18","男");
resumeA.setWorkExperience("533-537","武当派");
Resume resumeB = resumeA.clone();
resumeB.setWorkExperience("537-538", "波斯");
Resume resumeC = resumeA.clone();
resumeC.setWorkExperience("537-538", "波斯");
resumeA.display();
resumeB.display();
resumeC.display();
}
}
结果:
3.浅克隆和深克隆
由于简历里的对象都是string类型的,算是基本数据类型,clone方法只是把对象的引用拷贝过去,
所以当我门把工作经理脱离出去时,都是使用的最新的引用。
测试修改:
@Data
public class WorkExperience {
public String timeArea;
public String company;
}
@Data
public class Resume implements Cloneable {
private String name;
private String sex;
@Override
protected Resume clone() throws CloneNotSupportedException {
return (Resume)super.clone();
}
private String age;
private WorkExperience workExperience;
public Resume(String name) {
this.name = name;
workExperience = new WorkExperience();
}
//设置个人信息
public void setPersonalInfo(String age, String sex) {
this.sex = sex;
this.age = age;
}
//设置工作经历
public void setWorkExperience(String timeArea, String company) {
workExperience.timeArea =timeArea;
workExperience.company = company;
}
public void display() {
System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
System.out.println(String.format("工作经历:%s,%s", workExperience.getTimeArea(),workExperience.getCompany()));
}
}
public class AfterTest {
public static void main(String[] args) throws CloneNotSupportedException {
Resume resumeA = new Resume("张无忌");
resumeA.setPersonalInfo("18","男");
resumeA.setWorkExperience("533-537","武当派");
Resume resumeB = resumeA.clone();
resumeB.setWorkExperience("537-538", "波斯");
Resume resumeC = resumeA.clone();
resumeC.setWorkExperience("536-539", "明教");
resumeA.display();
resumeB.display();
resumeC.display();
}
}
结果如下,可以看到拷贝的对象中引用对象都是同一个。
解决办法:
让workExperience也实现cloneable接口修改如下:
@Data
public class WorkExperience implements Cloneable {
public String timeArea;
public String company;
@Override
protected WorkExperience clone() throws CloneNotSupportedException {
return (WorkExperience) super.clone();
}
}
简历类修改clone方法,并增加workExperience的构造方法:
/**
* @author dxy
* @version 1.0
* @date 2021/10/24 9:22
* @decripton 简历
* @mail victorydeng@163.com
*/
@Data
public class Resume implements Cloneable {
private String name;
private String sex;
public Resume(WorkExperience workExperience) throws CloneNotSupportedException {
this.workExperience = workExperience.clone();
}
@Override
protected Resume clone() throws CloneNotSupportedException {
Resume resume = new Resume(this.workExperience);
resume.age = this.age;
resume.name = this.name;
resume.sex = this.sex;
return resume;
}
private String age;
private WorkExperience workExperience;
public Resume(String name) {
this.name = name;
workExperience = new WorkExperience();
}
//设置个人信息
public void setPersonalInfo(String age, String sex) {
this.sex = sex;
this.age = age;
}
//设置工作经历
public void setWorkExperience(String timeArea, String company) {
workExperience.timeArea =timeArea;
workExperience.company = company;
}
public void display() {
System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
System.out.println(String.format("工作经历:%s,%s", workExperience.getTimeArea(),workExperience.getCompany()));
}
}
测试结果:
4.总结:
当我们需要new很多同个类型的对象时,而且这些对象初始化的信息没有很大变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高,,它等于昰不用重新初始化对象,而是动态地获得对象运行时的状态。