本文共 6487 字,大约阅读时间需要 21 分钟。
原型模式(ProtoType),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
该程序主要通过模拟复制简历的功能实现。
1、具体原型类
public class Resume implements Cloneable { private String name; private int age; private String sex; private String timeArea; private String company; public Resume(String name) { this.name = name; } /** * 设置个人信息 * @param sex * @param age */ public void setPersonInfo(String sex,int age){ this.sex = sex; this.age = age; } /** * 设置工作经历 * @param timeArea * @param company */ public void setWorkExperience(String timeArea,String company){ this.timeArea = timeArea; this.company = company; } public void display(){ System.out.println(this.name + ","+this.sex+","+this.age); System.out.println(this.timeArea+","+this.company); } public Object clone(){ Resume resume = null; try { resume =(Resume) super.clone(); }catch (CloneNotSupportedException e){ System.out.println(e); } return resume; }}
2、测试类
public class Test { public static void main(String[] args) { Resume resume1 = new Resume("aa"); resume1.setPersonInfo("male",25); resume1.setWorkExperience("2015-2018","xx公司"); Resume resume2 = (Resume) resume1.clone(); resume2.setWorkExperience("2015-2018","yy公司"); Resume resume3 = (Resume)resume1.clone(); resume3.setPersonInfo("female",29); resume1.display(); resume2.display(); resume3.display(); }}输出:aa,male,252015-2018,xx公司aa,male,252015-2018,yy公司aa,female,292015-2018,xx公司
在初始化信息不变的情况下,克隆是最好的办法。既隐藏了对象创建的细节,又大大提高了性能。
存在问题:
clone()方法中,如果字段是值类型,则对该字段进行逐位复制,如果该字段是引用类型,则复制引用但不复制
引用的对象,因此原始对象及其副本引用同一对象。
1、封装工作经历类
public class WorkExperience { private String timeArea; private String company; 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; }}
2、resume类修改
public class Resume implements Cloneable { private String name; private int age; private String sex; private WorkExperience workExperience; public Resume(String name) { this.name = name; workExperience = new WorkExperience(); } /** * 设置个人信息 * @param sex * @param age */ public void setPersonInfo(String sex,int age){ this.sex = sex; this.age = age; } /** * 设置工作经历 * @param timeArea * @param company */ public void setWorkExperience(String timeArea,String company){ workExperience.setTimeArea(timeArea);; workExperience.setCompany(company); } public void display(){ System.out.println(this.name + ","+this.sex+","+this.age); System.out.println(workExperience.getTimeArea()+","+workExperience.getCompany()); } public Object clone(){ Resume resume = null; try { resume =(Resume) super.clone(); }catch (CloneNotSupportedException e){ System.out.println(e); } return resume; }}
3、测试类
public class Test { public static void main(String[] args) { Resume resume1 = new Resume("aa"); resume1.setPersonInfo("male",25); resume1.setWorkExperience("2015-2018","xx公司"); Resume resume2 = (Resume) resume1.clone(); resume2.setWorkExperience("2015-2018","yy公司"); Resume resume3 = (Resume)resume1.clone(); resume3.setPersonInfo("female",29); resume1.display(); resume2.display(); resume3.display(); }}输出:aa,male,252015-2018,yy公司aa,male,252015-2018,yy公司aa,female,292015-2018,yy公司
可以看出输出的都是yy公司,存在浅复制问题。
“浅复制”,即被复制对象所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。而“深复制”则可把引用对象的变量指向复制过的新对象,而不是原来对象。
1、工作经历类实现cloneable接口,并重写clone方法
public class WorkExperience implements Cloneable{ private String timeArea; private String company; 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 Object clone(){ WorkExperience workExperience = null; try { workExperience =(WorkExperience) super.clone(); }catch (CloneNotSupportedException e){ System.out.println(e); } return workExperience; }}
2、简历类修改
public class Resume implements Cloneable { private String name; private int age; private String sex; private WorkExperience workExperience; public Resume(String name) { this.name = name; this.workExperience = new WorkExperience(); } private Resume(WorkExperience workExperience){ this.workExperience = (WorkExperience) workExperience.clone(); } public String getName() { return name; } public void setName(String name) { this.name = name; } /** * 设置个人信息 * @param sex * @param age */ public void setPersonInfo(String sex,int age){ this.sex = sex; this.age = age; } /** * 设置工作经历 * @param timeArea * @param company */ public void setWorkExperience(String timeArea,String company){ this.workExperience.setTimeArea(timeArea);; this.workExperience.setCompany(company); } public void display(){ System.out.println(this.name + ","+this.sex+","+this.age); System.out.println(workExperience.getTimeArea()+","+workExperience.getCompany()); } public Object clone(){ Resume resume = new Resume(this.workExperience); resume.setPersonInfo(this.sex,this.age); resume.setName(this.name); return resume; }}
3、测试
public class Test { public static void main(String[] args) { Resume resume1 = new Resume("aa"); resume1.setPersonInfo("male",25); resume1.setWorkExperience("2015-2018","xx公司"); Resume resume2 = (Resume) resume1.clone(); resume2.setWorkExperience("2015-2018","yy公司"); Resume resume3 = (Resume)resume1.clone(); resume3.setPersonInfo("female",29); resume1.display(); resume2.display(); resume3.display(); }}输出:aa,male,252015-2018,xx公司aa,male,252015-2018,yy公司aa,female,292015-2018,xx公司
注:参考文献《大话设计模式》程杰著。