原型模式:本质就是 浅复制 和深复制
是原型实力指定创建对象的种类,并且通过拷贝这些原型 创建新的对象
原型模式其实就是从一个对象再创建另外壹个 可定制的对象,而且不需要任何创建的细节
/**
* 原型模式:
* 学习原型模式之前,我们先看这样一个需求:
* 你的弟弟大学毕业了,要去准备面试找工作了,第一件事就是准备自己的简历,显然,一份简历是不够的,
* 写好简历需要去复印好几份,现在你的弟弟要你去复印简历(3份),简历上有姓名,性别,工作经历
* 你怎么做,你的代码可能是下面这样:Test1
* 一。看一看代码,想一想
* 1 :这样写,是输出了3份简历内容,但是,你只有一个对象,其他2份简历是啥,是第一份简历的引用,也就是谁
* 其他2份简历 指向第一份简历,这两份简历上是没有东西的,显然不对
* 二。怎么办
* 1.要不我new 3个对象???那复印20 份呢,new 20个,万一写错了,这20份是不是都要改,不能这样做
* 2.克隆去做 Test2
* */
public class Test1 {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
public Test1(String name) {
this.name=name;
}
//设置个人信息
public void setPserinfo(String age,String sex) {
this.age=age;
this.sex=sex;
}
//设置个人经历
public void setWork(String timeArea,String company) {
this.timeArea=timeArea;
this.company=company;
}
// 显示
public void show() {
System.out.println(name+age+sex);
System.out.println("工作经历:"+timeArea+company);
}
//客户端
public static void main(String[] args) {
Test1 test1 = new Test1("弟弟");
test1.setPserinfo("18", "男");
test1.setWork("2016-2018", "阿里");
test1.show();
test1.show();
test1.show();
}
}
Test2
/**
* 看一看代码:
* 1.输出了 3份简历,每份简历你想修改,只需要对某份简历做特定的修改就可以了。
* 2.相对于new 3个简历,这样做的好处是:每new 一次,都要执行一次构造函数。如果,这个构造函数的
* 执行时间很长,那么多次执行这个初始化操作实在是 太低效了,一般在初始化的信息不发生变化的情况下,
* 克隆是最好的方法。这既隐藏了对象创建的细节。又对性能是大大的提高。
* 2.她等于是 不用重新初始化对象,而是动态得获取运行时的状态
* 想一想:
* 1.现在改需求了:Test2对象(简历) 中的数据都是 String 类型,如果字段都是引用类型,则
* 复制引用单不复制引用的对象,所以Test2 指的是 浅复制,不信,看Test3
* */
public class Test2 implements Cloneable {
private String name;
private String sex;
private String age;
private String timeArea;
private String company;
public Test2(String name) {
this.name = name;
}
// 设置个人信息
public void setPserinfo(String age, String sex) {
this.age = age;
this.sex = sex;
}
// 设置个人经历
public void setWork(String timeArea, String company) {
this.timeArea = timeArea;
this.company = company;
}
// 显示
public void show() {
System.out.println(name + age + sex);
System.out.println("工作经历:" + timeArea + company);
}
// 重写克隆 方法
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
// 客户端
public static void main(String[] args) {
Test2 test2 = new Test2("弟弟");
test2.setPserinfo("12", "男");
test2.setWork("2015-2017", "腾讯");
// 第二份简历
try {
Test2 clone = (Test2) test2.clone();
clone.setWork("2016-2017", "百度");
// 第三份简历
Test2 clone1 = (Test2) test2.clone();
clone1.setWork("2017-2018", "阿里");
// 打印简历
test2.show();
clone.show();
clone1.show();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Test3
public class WorkJL {
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;
}
}
/**
* 浅复制
* 看一看:输出结果,一模一样。
* 分析一下:
* 1.三个引用都指向了最后一次,这就是浅复制:被复制对象的所有变量都含有与原来的对象
* 相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
* 2。如果含有对象的引用,需要把复制的对象所引用的对象都复制一遍。这就涉及到深复制:
* 深复制把引用对象的变量指向复制过来的新对象,而不是原有的被引用的对象。
* 看Test4
*
* */
public class Test3 implements Cloneable{
private String name;
private String sex;
private String age;
// 包含引用
private WorkJL workJL;
public Test3(String name) {
this.name = name;
workJL=new WorkJL();
}
// 设置个人信息
public void setPserinfo(String age, String sex) {
this.age = age;
this.sex = sex;
}
// 设置个人经历
public void setWork(String timeArea, String company) {
workJL.timeArea = timeArea;
workJL.company = company;
}
// 显示
public void show() {
System.out.println(name + age + sex);
System.out.println("工作经历:" + workJL.timeArea + workJL.company);
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
// 客户端
public static void main(String[] args) {
Test3 test = new Test3("弟弟");
test.setPserinfo("12", "男");
test.setWork("2015-2017", "腾讯");
// 第二份简历
try {
Test3 clone = (Test3) test.clone();
clone.setWork("2016-2017", "百度");
// 第三份简历
Test3 clone1 = (Test3) test.clone();
clone1.setWork("2017-2018", "阿里");
// 打印简历
test.show();
clone.show();
clone1.show();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
test4
public class WorkJLs implements Cloneable,Serializable{
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
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
/**
* 深复制:
* 在一些特定场合,会经常涉及到深复制或浅复制,比如说,
* 1.数据集对象DataSet,他就有Clone()和copy() 方法,clone() 方法用来复制DataSet
* 数据结构,但不复制DataSet的数据,实现了原型模式的浅复制,copy()方法不但复制
* 结构,也不复制数据,其实就是实现了原型模式的深复制
* */
public class Test4 implements Cloneable,Serializable{
private String name;
private String sex;
private String age;
// 包含引用
private WorkJLs workJL;
public Test4(String name) {
this.name = name;
workJL=new WorkJLs();
}
// 提供克隆方法,对经历克隆
public Test4(WorkJLs workJLs) {
try {
this.workJL=(WorkJLs)workJLs.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//
// 设置个人信息
public void setPserinfo(String age, String sex) {
this.age = age;
this.sex = sex;
}
// 设置个人经历
public void setWork(String timeArea, String company) {
workJL.timeArea = timeArea;
workJL.company = company;
}
// 显示
public void show() {
System.out.println(name + age + sex);
System.out.println("工作经历:" + workJL.timeArea + workJL.company);
}
@Override
protected Object clone() throws CloneNotSupportedException {
Test4 test4 = new Test4(this.workJL);
test4.name=this.name;
test4.age=this.age;
test4.sex=this.sex;
return test4;
}
// 客户端
public static void main(String[] args) {
Test4 test = new Test4("弟弟");
test.setPserinfo("12", "男");
test.setWork("2015-2017", "腾讯");
// 第二份简历
try {
Test4 clone = (Test4) test.clone();
clone.setWork("2016-2017", "百度");
// 第三份简历
Test4 clone1 = (Test4) test.clone();
clone1.setWork("2017-2018", "阿里");
// 打印简历
test.show();
clone.show();
clone1.show();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}