原型模式
1、模式详解
(1)、在开发过程中,有时会遇到为一个类创建多个实例的情况,这些实例内部成员往往完全相同或有细微的差异,而且实例的创建开销比较大或者需要输入较多参数,如果能通过复制一个已创建的对象实例来重复创建多个相同的对象,这就可以大大减少创建对象的开销,这个时候就需要原型模式。
(2)、原型模式可以通过一个对象实例确定创建对象的种类,并且通过拷贝创建新的实例。总得来说,原型模式实际上就是从一个对象创建另一个新的对象,使新的对象有具有原对象的特征。
(3)、UML类图:
(4)、代码实现:
1、创建一个工作经验类:
public class WorkExperience { public String timeArea; public String company; public WorkExperience() { // TODO Auto-generated constructor stub } //getter,seter和toString方法 }
2、创建一个简历类:
package com.yuanxingGOF; import java.util.ArrayList; import java.util.List; public class Resume implements Cloneable{ public String name; public String sex; public int age; public WorkExperience work; public List<String> family = new ArrayList<String>(); public Resume() { // TODO Auto-generated constructor stub } public Resume(String name,List<String> fam) { this.name=name; this.family=fam; this.work = new WorkExperience(); } public void setName(String name){ this.name=name; } public void setPersonal(String sex,int age){ this.sex=sex; this.age=age; } public void setWorkExperience(String timeArea ,String company){ work.setTimeArea(timeArea); work.setCompany(company); } // 浅拷贝 /*@Override protected Object clone() throws CloneNotSupportedException { return (Resume)super.clone(); }*/ //深拷贝 public Object clone() throws CloneNotSupportedException { String name = new String(this.getName()); String sex=new String(this.getSex()); int age = this.getAge(); ArrayList<String> famMem = new ArrayList<>(this.getFamily()); Resume copy = new Resume(name, famMem); copy.setPersonal(sex, age); copy.setWorkExperience(this.getWork().getTimeArea(), this.getWork().getCompany());; return copy; } public void disply(){ System.out.println("名字:"+this.name); System.out.println("家庭成员"); for(String a:this.family){ System.out.print(a+"\t"); } System.out.println(); System.out.println("性别"+this.getSex()+"age:"+this.getAge()); System.out.println("工作经验:"+this.getWork()); } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public WorkExperience getWork() { return work; } public void setWork(WorkExperience work) { this.work = work; } public List<String> getFamily() { return family; } public void setFamily(List<String> family) { this.family = family; } public String getName() { return name; } }
3、测试类:
package com.yuanxingGOF; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) throws CloneNotSupportedException { List<String> am = new ArrayList<String>(); am.add("die"); am.add("sistem"); Resume person1 = new Resume("toms",am); person1.setPersonal("男", 18); person1.setWorkExperience("2014-11-11到2015-12-12", "jj"); List<String> am1 = new ArrayList<String>(); am1.add("die111"); am1.add("sistem111"); Resume person2 = (Resume) person1.clone(); person2.setName("tom"); person2.setPersonal("女", 21); person2.setFamily(am1); // person2.setWorkExperience("2016-11-11到2018-12-12", "baodu"); person1.disply(); person2.disply(); System.out.println(person1==person2); /*System.out.println(person1.getWork().hashCode()); System.out.println(person2.getWork().hashCode());*/ System.out.println(person1.getName().hashCode()); System.out.println(person2.getName().hashCode()); System.out.println(person1.getWork().hashCode()); System.out.println(person2.getWork().hashCode()); } }
结果:
名字:toms 家庭成员 die sistem 性别男age:18 工作经验:WorkExperience [timeArea=2014-11-11到2015-12-12, company=jj] 名字:tom 家庭成员 die111 sistem111 性别女age:21 工作经验:WorkExperience [timeArea=2014-11-11到2015-12-12, company=jj] false 3565921 115026 366712642 1829164700
备注:深拷贝:拷贝初始化后,workExperience就是2个地址。
简而言之深拷贝就是重写clone方法,不使用(Resume)super.clone();而是重新new一个。