原型模型
原型模式其实就是从一个对象基础上再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
原型模型可以大大提高效率。一般在初始化的信息不发生变化的情况下,克隆是最好的办法,即隐藏了创建对象的细节,又对性能有大大的提升。
看代码就知道怎么回事了。以书写简历为例:
public class Resume implements Cloneable{
String name;
String sex;
String age;
String timearea;
String company;
public Resume(String name) {
super();
this.name = name;
}
public Resume() {
super();
}
//设置个人信息
public void setPersonInfo(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 name + " " + sex + " " + age + "\n工作经历:" + timearea + " "
+ company;
}
public Object Clone() throws Exception{
return this.clone();
}
}
public class Test {
public static void main(String[] args) throws Exception {
Resume a = new Resume("大鸟");
a.setPersonInfo("男", "20岁");
a.setWorkExperience("2013-2017", "东北林业大学");
Resume b = (Resume)a.Clone();
b.setWorkExperience("2017-2022", "哈尔滨工业大学");
Resume c = (Resume)a.Clone();
c.setWorkExperience("2022-2030", "google");
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
输出结果:
大鸟 男 20岁
工作经历:2013-2017 东北林业大学
大鸟 男 20岁
工作经历:2017-2020 哈尔滨工业大学
大鸟 男 20岁
工作经历:2020-2022 google
注:上述代码是原型模型的浅复制,只能复制值类型的数据,对于引用类型的对象不能复制。
如果将工作经历也单独做一个类,然后在resume类中应用工作经历,就会输出3条一模一样的结果。
浅复制被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都任指向原来的对象。
将工作经历也单独做一个类的代码:
public class WorkExperience {
String timearea;
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;
}
@Override
public String toString() {
return "\n工作经历" + timearea + " " + company;
}
}
public class Resume implements Cloneable{
String name;
String sex;
String age;
WorkExperience work;
public Resume(String name) {
super();
this.name = name;
work = new WorkExperience();
}
public Resume() {
super();
}
//设置个人信息
public void setPersonInfo(String sex,String age){
this.sex = sex;
this.age = age;
}
public void setWorkExperience(String timearea,String company){
work.timearea = timearea;
work.company = company;
}
@Override
public String toString() {
return name + " " + sex + " " + age + work ;
}
public Object Clone() throws Exception{
return this.clone();
}
}
输出结果
大鸟 男 20岁
工作经历:2020-2022 google
大鸟 男 20岁
工作经历:2020-2022 google
大鸟 男 20岁
工作经历:2020-2022 google
深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
二层深复制的代码:
public class WorkExperience implements Cloneable{
String timearea;
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;
}
@Override
public String toString() {
return "\n工作经历" + timearea + " " + company;
}
public Object Clone() throws Exception{
return this.clone();
}
}
public class Resume implements Cloneable{
String name;
String sex;
String age;
WorkExperience work;
public Resume(String name) {
super();
this.name = name;
work = new WorkExperience();
}
public Resume() {
super();
}
private Resume(WorkExperience work) throws Exception {
super();
this.work = (WorkExperience)work.Clone();
}
//设置个人信息
public void setPersonInfo(String sex,String age){
this.sex = sex;
this.age = age;
}
public void setWorkExperience(String timearea,String company){
work.timearea = timearea;
work.company = company;
}
@Override
public String toString() {
return name + " " + sex + " " + age + work ;
}
public Object Clone() throws Exception{
Resume obj = new Resume(this.work);
obj.name = this.name;
obj.age = this.age;
obj.sex = this.sex;
return obj;
}
}
输出结果:
大鸟 男 29岁
工作经历2013-2017 东北林业大学
大鸟 男 29岁
工作经历2017-2022 哈尔滨工业大学
大鸟 男 29岁
工作经历2020-2030 google
代码改动的地方:
让WorkExperience类也实现了Cloneable的接口,并增加了clone()方法。
在resume类中新增了一个私有的构造方法。
修改了resume的clone()的方法。
往期回顾