原型是一种创建型设计模式, 使你能够复制对象, 甚至是复杂对象, 而又无需使代码依赖它们所属的类。所有的原型类都必须有一个通用的接口, 使得即使在对象所属的具体类未知的情况下也能复制对象。
原型模式分为浅复制和深复制。
浅复制:将一个对象复制之后,生成一个新的对象,新对象的所有成员变量(基本类型或引用类型)都含有与原有对象相同的值,如果原有对象的成员变量是基本数据类型,就会将这个变量的值复制一份到新对象里面,如果原有对象的成员变量是引用数据类型,那么这个引用指向的对象不会新生成一份,而是,在新对象里面的这个引用与原有对象的引用指向的是同一个对象。
浅复制,基本数据类型
1. Citation.java
package prototype2;
/**
* Author:
* Created: 2024/09/29 14:01
* Description:
*/
public class Citation implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show() {
System.out.println(name + "同学: 表现优秀,特发此奖状!!!");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
CitationTest.java
package prototype2;
/**
* Author:
* Created: 2024/09/29 14:05
* Description:
*/
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
//1.创建原型对象
Citation citation = new Citation();
//克隆奖状对象
Citation citation2 = citation.clone();
citation.setName("张三");
citation2.setName("李四");
citation.show();
citation2.show();
System.out.println(citation == citation2);
}
}
执行结果:
张三同学: 表现优秀,特发此奖状!!!
李四同学: 表现优秀,特发此奖状!!!
falseProcess finished with exit code 0
2. 浅复制,引用数据类型
Citation.java
package prototype3;
/**
* Author:
* Created: 2024/09/29 14:01
* Description:
*/
public class Citation implements Cloneable {
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public void show() {
System.out.println(student.getName() + "同学: 表现优秀,特发此奖状!!!");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
Student.java
package prototype3;
/**
* Author:
* Created: 2024/09/29 14:01
* Description:
*/
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
CitationTest.java
package prototype3;
/**
* Author:
* Created: 2024/09/29 14:05
* Description:
*/
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
//1.创建原型对象
Citation citation = new Citation();
Student student = new Student();
student.setName("张三");
citation.setStudent(student);
//克隆奖状对象
Citation citation2 = citation.clone();
citation2.getStudent().setName("李四");
citation.show();
citation2.show();
System.out.println(citation == citation2);
Citation citation3 = citation.clone();
}
}
执行结果:
李四同学: 表现优秀,特发此奖状!!!
李四同学: 表现优秀,特发此奖状!!!
falseProcess finished with exit code 0
浅复制在引用数据类型时,引用指向的对象不会新生成一份,当修改student对象name时,原来被复制的对象的引用类型student的name属性也被改成了“李四”,为了实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出该二进制数据对应的对象。
深复制:将一个对象复制之后,生成一个新的对象,新对象的基本数据类型变量含有与原有对象相同的值,如果原有对象的成员变量是引用数据类型,在新对象里面,这些引用变量将指向被复制过的新对象,而不再是指向原有的那些被引用的对象,深复制把要复制的对象所引用的对象都复制一遍。为了实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出该二进制数据对应的对象。
3. 深复制,引用数据类型
Citation.java
package prototype4;
import java.io.Serializable;
/**
* Author:
* Created: 2024/09/29 14:01
* Description:
*/
public class Citation implements Cloneable, Serializable {
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public void show() {
System.out.println(student.getName() + "同学: 表现优秀,特发此奖状!!!");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
Student.java
package prototype4;
import java.io.Serializable;
/**
* Author:
* Created: 2024/09/29 14:01
* Description:
*/
public class Student implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
CitationTest.java
package prototype4;
import java.io.*;
/**
* Author:
* Created: 2024/09/29 14:05
* Description:
*/
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
//1.创建原型对象
Citation citation = new Citation();
Student student = new Student();
student.setName("张三");
citation.setStudent(student);
//创建对象输出流对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:/IdeaProjects/design-pattern/protype"));
//写对象
objectOutputStream.writeObject(citation);
//释放资源
objectOutputStream.close();
//创建对象输入流对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:/IdeaProjects/design-pattern/protype"));
//读取对象
Citation citation2 = (Citation) objectInputStream.readObject();
objectInputStream.close();
citation2.getStudent().setName("李四");
citation.show();
citation2.show();
}
}
执行结果:
张三同学: 表现优秀,特发此奖状!!!
李四同学: 表现优秀,特发此奖状!!!Process finished with exit code 0