创建者模式-原型模式
概述
用一个已经创建的实例作为原型,通过复制该类原型对象来创建一个和原型对象相同的新对象
结构
- 抽象原型类:规定了具体原型对象必须实现的clone()方法
- 具体原型类:实现抽象原型类的clone()方法,它是可被复制的对象
- 访问类:使用具体原型类中的clone()方法来复制新的对象
实现
原型模式的克隆分为浅克隆和深克隆
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址
浅克隆
Java中的Object类中提供了clone()方法来实现浅克隆,Cloneable接口是抽象原型类,实现了Cloneable接口的子实现就是具体的原型类
//数据类
@lombok.Data
public class Data {
public String name;
public Integer age;
}
//学生类
public class Student implements Cloneable{
public Data data;
public Student(){
System.out.println("使用了构造函数");
}
@Override
public Student clone() throws CloneNotSupportedException {
System.out.println("进行克隆函数操作");
return (Student) super.clone();
}
}
//测试类
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Data test1 = new Data();
test1.name = "张三";
test1.age = 10;
Student student = new Student();
student.data = test1;
Student clone = student.clone();
System.out.println(student.data == clone.data);
student.data.age = 100;
System.out.println(student.data);
System.out.println(clone.data);
System.out.println(clone == student);
}
}
/*
使用了构造函数
进行克隆函数操作
true
Data(name=张三, age=100)
Data(name=张三, age=100)
false
*/
深克隆
具体实现思路为,将需要被克隆的对象进行本地序列化,然后通过文件流读取序列化后的信息进行创建
public class Test {
public static void main(String[] args) throws Exception {
Data test1 = new Data();
test1.name = "张三";
test1.age = 10;
Student student = new Student();
student.data = test1;
String currentDir = System.getProperty("user.dir");
//序列化
String pathName = currentDir + "\\src\\main\\resources\\file\\";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pathName + "deepClone.txt"));
oos.writeObject(student);
//返序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathName + "deepClone.txt"));
Student clone = (Student) ois.readObject();
System.out.println(student.data == clone.data);
student.data.age = 100;
System.out.println(student.data);
System.out.println(clone.data);
System.out.println(clone == student);
}
}
/*
运行结果如下
使用了构造函数
false
Data(name=张三, age=100)
Data(name=张三, age=10)
false
*/