概念:
* 原型模式:也可以说是克隆模式。
* 通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以用原型模式。
* 就是java的克隆技术,以某个对象为原型,复制出新的对象,显然,新的对象具备原型对象的特点。
* 优势:效率高:直接克隆,避免了重新执行构造过程步骤。
* 克隆不同于new,new出来的对象属性是默认值,克隆出来的属性完全和原型相同,并且修改不会影响到
* 原型。
实现:
* 实现:Cloneable接口和clone方法
* clone方法不是Cloneable接口里的方法,Cloneable接口是个标记接口,空的。
* clone方法是object里的方法。
1997年克隆羊多利的出现,克隆这个概念就产生了,以羊为例子来写。
public class Sheep implements Cloneable{ //1997,克隆多利羊
private String name;
private Date birthday;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
public Sheep(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
public Sheep(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
测试:
Date d = new Date(314312432542L);
Sheep sheep = new Sheep("少利", d);
Sheep sheep2 = (Sheep) sheep.clone();
sheep2.setName("多利");
System.out.println(sheep);
System.out.println(sheep.getName());
System.out.println(sheep.getBirthday());
System.out.println(sheep2);
System.out.println(sheep2.getName());
System.out.println(sheep2.getBirthday());
结果:
cn.oyh.GOF23.prototype.Sheep@1540e19d
少利
Tue Dec 18 05:00:32 CST 1979
cn.oyh.GOF23.prototype.Sheep@135fbaa4
多利
Tue Dec 18 05:00:32 CST 1979
但是这样是有问题的,把时间改一下,看下结果:
Date d = new Date(314312432542L);
Sheep sheep = new Sheep("少利", d);
Sheep sheep2 = (Sheep) sheep.clone();
sheep2.setName("多利");
System.out.println(sheep);
System.out.println(sheep.getBirthday());
d.setTime(43254356246L);
System.out.println(sheep.getName());
System.out.println(sheep.getBirthday());
System.out.println(sheep2);
System.out.println(sheep2.getName());
System.out.println(sheep2.getBirthday());
cn.oyh.GOF23.prototype.Sheep@1540e19d
Tue Dec 18 05:00:32 CST 1979
少利
Sun May 16 23:05:56 CST 1971
cn.oyh.GOF23.prototype.Sheep@135fbaa4
多利
Sun May 16 23:05:56 CST 1971
可以发现,sheep把时间改了,sheep2的时间也变了。这就是涉及到浅克隆和深克隆了。
*浅克隆:sheep、sheep2都指向了同一个Date,如果sheep修改了时间,那么sheep2的时间也跟着变。
* 深克隆:sheep2克隆出来的时候,也克隆了一个新的Date,两个sheep各自指着自己的Date。
* 也就是对象下面的属性也进行拷贝。
要实现深克隆,只需在clone()方法里改:
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
// 添加下面代码进行深克隆
Sheep s = (Sheep) obj;
s.birthday = (Date) this.birthday.clone();//把属性进行克隆
return obj;
}
再测试:
cn.oyh.GOF23.prototype.Sheep@1540e19d
Tue Dec 18 05:00:32 CST 1979
少利
Sun May 16 23:05:56 CST 1971
cn.oyh.GOF23.prototype.Sheep@135fbaa4
多利
Tue Dec 18 05:00:32 CST 1979
sheep2的时间没有改变。 也可以通过序列化和反序列化来实现深克隆,就是用IO流来写,我这就不写了。