1、原型模式
例:假设应聘时需要准备简历,用Java实现创建三个简历:
//创建一个简历类
public class Resume implements Cloneable {
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 sex,String age) {
this.sex = sex;
this.age = age;
}
/*
* 设置工作经验
*/
public void setWorkExperience(String timeArea,String company) {
this.timeArea = timeArea;
this.company = company;
}
@Override
public String toString() {
return "Resume [name=" + name + ", sex=" + sex + ", age=" + age + ", timeArea=" + timeArea + ", company="
+ company + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//主函数测试类
public class Test {
public static void main(String[] args) {
Resume resume = new Resume("大话设计模式");
resume.setPersonalInfo("男", "29");
resume.setWorkExperience("1998-2000", "不知道啥公司");
System.out.println(resume.toString());
try {
Resume resume2 = (Resume) resume.clone();
resume2.setWorkExperience("2000-2003", "不知道啥公司");
System.out.println(resume2.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
-
优点:
1、一般在初始化的信息不可发生变化的情况下,克隆是最好的方法,这即隐藏了对象创建的细节,又对 性能是大大的提高
2、不用重新初始化对象,而是动态的获取得到对象运行时的状态
-
缺点:
相对来说采用的是浅复制的做法,在引用类型时会出现问题
1.1、浅复制和深复制
浅复制缺点:
1、当简历对象中存在引用类型时那么这种方式复制的是引用而不是复制的对象
如下代码
/**
* @Title: WorkExperience.java
* @Description: 工作经历
* @date :2020年1月3日 下午1:27:09
*/
public class WorkExperience {
private String WorkDate;
private String company;
public String getWorkDate() {
return WorkDate;
}
public void setWorkDate(String workDate) {
WorkDate = workDate;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public String toString() {
return "WorkExperience [WorkDate=" + WorkDate + ", company=" + company + "]";
}
}
/**
* @version:V1.0
* @Title: Resume.java
* @Description: 简历类
* @date :2020年1月3日 下午1:30:42
*/
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private WorkExperience workExperience;
public Resume(String name) {
this.name = name;
workExperience = new WorkExperience();
}
/*
* 设置个人信息
*/
public void setPersonalInfo(String sex,String age) {
this.age = age;
this.sex = sex;
}
/*
* 设置工作经验
*/
public void setWorkExperience(String workDate,String company) {
System.out.println(workDate + "==========" + company);
workExperience.setWorkDate(workDate);
workExperience.setCompany(company);
}
@Override
public String toString() {
return "Resume [name=" + name + ", sex=" + sex + ", age=" + age + ", workExperience=" + workExperience + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/**
* @Title: main
* @Description:主函数测试类
*/
public class Test {
public static void main(String[] args) {
Resume resume = new Resume("大话设计模式");
resume.setPersonalInfo("男", "29");
resume.setWorkExperience("1998-2000", "不知道啥公司");
try {
Resume resume2 = (Resume) resume.clone();
resume2.setWorkExperience("2000-2003", "不知道啥公司");
Resume resume3 = (Resume) resume.clone();
resume3.setWorkExperience("2001-2004", "不知道啥公司");
System.out.println(resume.toString());
System.out.println(resume2.toString());
System.out.println(resume3.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
此时的运行结果是
1998-2000==========不知道啥公司
2000-2003==========不知道啥公司
2001-2004==========不知道啥公司
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=2001-2004, company=不知道啥公司]]
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=2001-2004, company=不知道啥公司]]
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=2001-2004, company=不知道啥公司]]
我们发现三次输出的结果都是最后一次修改的值,也就是说克隆时只是将对象的引用复制过来了,实际三次操作同一个工作经历对象了。
此时我们需要给工作经历对象重写克隆方法
/**
* @Title: WorkExperience.java
* @Description: 工作经历
* @date :2020年1月3日
*/
public class WorkExperience implements Cloneable{
private String WorkDate;
private String company;
public String getWorkDate() {
return WorkDate;
}
public void setWorkDate(String workDate) {
WorkDate = workDate;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public String toString() {
return "WorkExperience [WorkDate=" + WorkDate + ", company=" + company + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/**
* @version:V1.0
* @Title: Resume.java
* @Description: 简历类添加构造函数
*/
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private WorkExperience workExperience;
public Resume(String name) {
this.name = name;
workExperience = new WorkExperience();
}
/**
* 提供克隆方法调用私有构造函数,以便克隆工作经历的数据
*/
public Resume(WorkExperience workExperience) {
try {
this.workExperience = (WorkExperience) workExperience.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
/*
* 设置个人信息
*/
public void setPersonalInfo(String sex,String age) {
this.age = age;
this.sex = sex;
}
/*
* 设置工作经验
*/
public void setWorkExperience(String workDate,String company) {
System.out.println(workDate + "==========" + company);
workExperience.setWorkDate(workDate);
workExperience.setCompany(company);
}
@Override
public String toString() {
return "Resume [name=" + name + ", sex=" + sex + ", age=" + age + ", workExperience=" + workExperience + "]";
}
//重写克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
Resume resume = new Resume(this.workExperience);
resume.name = this.name;
resume.sex = this.sex;
resume.age = this.age;
return resume;
}
}
此时的结果便是我们想要的状态
1998-2000==========不知道啥公司
2000-2003==========不知道啥公司
2001-2004==========不知道啥公司
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=1998-2000, company=不知道啥公司]]
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=2000-2003, company=不知道啥公司]]
Resume [name=大话设计模式, sex=男, age=29, workExperience=WorkExperience [WorkDate=2001-2004, company=不知道啥公司]]
也就是说为了是我们的克隆我们需要把对应的引用类型的实体类也实现克隆方法,而本类中需要提供克隆方法调用私有构造函数,以便克隆引用类的数据,同时重写clone
方法。
注:整体思想和案例借鉴大话设计模式:本帖为本人自学的笔记,不喜勿喷