原型模式
看完建造者模式之后,我来到了创建型模式的最后一个部分—-原型模式
理解
定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
使用场景:当我们通过new产生一个对象需要非常繁琐的数据准备或者访问权限,则可以使用原型模式,这样可以提高效率
注意:
1、区分什么是深复制、什么是浅复制
2、原型模式中的原型对象需要实现Cloneable接口
3、用序列化和反序列化实现深克隆时,原型对象还需要需要实现Serializable接口
代码样例
1、浅复制
我们创建一个继承Cloneable接口的Sheep类,并且重写clone()方法
import java.io.Serializable;
import java.util.Date;
public class Sheep implements Cloneable, Serializable {
private String name;
private Date birthday;
@Override
protected Object clone() throws CloneNotSupportedException {
// 浅复制仅仅是对原型对象进行克隆,并不克隆原型对象的属性所指向的那个对象
Object object = super.clone();
return object;
}
public Sheep() {
}
public Sheep(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
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;
}
}
然后写个测试类,使用clone()方法克隆出两个新的对象sheep2和sheep3
import java.util.Date;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(1234231231L);
Sheep sheep1 = new Sheep("多莉", date);
System.out.println(sheep1.getName());
System.out.println(sheep1.getBirthday());
Sheep sheep2 = (Sheep) sheep1.clone();
System.out.println(sheep2.getName());
System.out.println(sheep2.getBirthday());
Sheep sheep3 = (Sheep) sheep1.clone();
// 浅复制时,修改原型对象的属性值,会影响之前的克隆对象
date.setTime(12314112312L);
System.out.println(sheep3.getName());
System.out.println(sheep3.getBirthday());
}
}
运行测试类之后,可以看出修改原型对象sheep1的属性值后,会影响到克隆对象sheep3的属性
因为浅复制时,克隆对象的属性所指向也是原型对象的属性
2、深复制
我们创建一个继承Cloneable接口的Sheep2类,并且重写clone()方法,与浅复制不同的是,我们对原型对象的属性也进行了克隆
import java.util.Date;
public class Sheep2 implements Cloneable {
private String name;
private Date birthday;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
// 要实现深复制,就需要在重写clone方法时对原型对象的属性也进行克隆,相当于创建了一个新的对象去赋值给克隆对象的属性
Sheep2 sheep2 = (Sheep2) obj;
sheep2.birthday = (Date) this.birthday.clone();
return sheep2;
}
public Sheep2() {
}
public Sheep2(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
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;
}
}
同样的我们编写一个测试类进行测试
import java.util.Date;
public class Client2 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(12314123113L);
Sheep2 sheep = new Sheep2();
sheep.setName("多莉2");
sheep.setBirthday(date);
System.out.println(sheep.getName());
System.out.println(sheep.getBirthday());
Sheep2 sheep2 = (Sheep2) sheep.clone();
// 深复制时,修改原对象的属性,不会对已经克隆好的对象产生影响
date.setTime(12314112312L);
System.out.println(sheep2.getName());
System.out.println(sheep2.getBirthday());
}
}
运行测试类之后,可以看出修改原型对象的属性值后,不会影响到克隆对象的属性
因为深复制时,克隆对象的属性所指向不再是原型对象的属性,我们相当于创建了一个新的属性对象赋予给克隆对象的那个属性,所以即使原型对象的属性值变了也不会对克隆对象产生影响
3、使用序列化与反序列化实现深复制
我们在创建Sheep类时,还需要继承一个Serializable接口
然后我们编写测试类进行测试
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class Client3 {
public static void main(String[] args) throws Exception {
Date date = new Date(1234231231L);
Sheep sheep1 = new Sheep("多莉", date);
System.out.println(sheep1.getBirthday());
// 注意,使用序列化与反序列化深克隆原型对象时,原型对象的类需要实现Serializable接口
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(sheep1);
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream inputStream = new ObjectInputStream(bis);
Sheep sheep2 = (Sheep) inputStream.readObject();
date.setTime(12314112312L);
System.out.println(sheep2.getBirthday());
}
}
我们发现,即使修改了原型对象的属性值,也不会对克隆的对象产生影响
如有错误,欢迎指正
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136822.html