Prototype mode
* Personal Blog: www.xiaobeigua.icu
1.1 Overview
Use a created instance as a prototype and copy the prototype object to create a new object that is the same as the prototype object.
1.2 Structure
The prototype pattern contains the following roles:
- Abstract prototype class: A clone() method that specifies what a specific prototype object must implement.
- Specific prototype class: The clone() method that implements the Abstract prototype class, which is a replicable object.
- Access class: Copy new objects using the clone() method in the concrete prototype class.
The class diagram is as follows:
1.3 Implementation
The clones of prototype pattern are divided into shallow clone and deep clone.
Shallow cloning: Create a new object with the same properties as the original object, and for non-basic type properties, still point to the memory address of the object that the original property points to.
(that is, the eight basic types are new objects created, while the reference type or the address of the reference type of the original object is equivalent to no reference type being cloned from it)
Deep cloning: Create a new object, and other objects referenced in the attribute will also be cloned, no longer pointing to the address of the original object.
The clone() method is provided in the Object class in Java to implement shallow cloning. The Cloneable interface is an abstract prototype class in the class diagram above, while the subimplementation class that implements the Cloneable interface is the concrete prototype class.
Code:
Prototype class:
/** * Create a prototype class of Beigua to clone multiple Beigua */ public class CloneType implements Cloneable { //Parametric construction public CloneType(){ System.out.println("Successfully created Xiao Beiguan prototype object"); } //Methods to override the clone interface @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
Test class:
public class test { public static void main(String[] args) throws CloneNotSupportedException { System.out.println("Start creating the prototype object of Little Beigua"); CloneType cloneType1=new CloneType(); System.out.println("Start cloning Little Beigua"); CloneType cloneType2=(CloneType) cloneType1.clone(); System.out.println("Cloning object succeeded"); System.out.println("Are the two classes the same object address?"+(cloneType1==cloneType2)); } }
Result:
The result shows that the cloned object is a completely new object and does not share an address with the original object
1.4 Cases
Generate the "Three Good Students" award using prototype mode
The "Three Good Students" awards of the same school are the same except for the names of the winners. You can use the prototype mode to duplicate multiple "Three Good Students" awards and then modify the names on the awards.
Class Diagram:
Code:
Awards:
public class Citation implements Cloneable { private String name; public void setName(String name) { this.name = name; } public String getName() { return (this.name); } public void show() { System.out.println(name + "Classmate: Excellent performance in the first semester of the 2020 school year, and was rated as the "Three Good Students". Special!"); } @Override public Citation clone() throws CloneNotSupportedException { return (Citation) super.clone(); } }
Test Class:
public class CitationTest { public static void main(String[] args) throwsCloneNotSupportedException { Citation c1 = new Citation(); c1.setName("Zhang San"); //Copy the award Citation c2 = c1.clone(); //Modify the name of the certificate to Li Si c2.setName("Li Si"); c1.show(); c2.show(); } }
Result:
1.5 Use scenarios
- Object creation is complex, and you can quickly create objects using prototype mode.
- High performance and security requirements.
1.6 Extension (Deep Cloning)
Modify the name property of the Citation class to the Student type property in the case of the Triple Good Student award above.
Code:
Awards:
//Awards public class Citation implements Cloneable { private Student stu; public Student getStu() { return stu; } public void setStu(Student stu) { this.stu = stu; } void show() { System.out.println(stu.getName() + "Classmate: Excellent performance in the first semester of the 2020 school year, and was rated as the "Three Good Students". Special!"); } @Override public Citation clone() throws CloneNotSupportedException { return (Citation) super.clone(); } }
Student Class:
//Student Class public class Student { private String name; private String address; public Student(String name, String address) { this.name = name; this.address = address; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
Test class:
public class CitationTest { public static void main(String[] args) throwsCloneNotSupportedException { Citation c1 = new Citation(); Student stu = new Student("Zhang San", "Xi'an"); c1.setStu(stu); //Copy the award Citation c2 = c1.clone(); //Student to whom the c2 Award is awarded Student stu1 = c2.getStu(); stu1.setName("Li Si"); //Determine if stu object and stu1 object are the same object System.out.println("stu and stu1 Is it the same object?" + (stu == stu1)); c1.show(); c2.show(); } }
Result:
Description:
The stu1 object and stu1 object are the same object, which will result in changing the name attribute value of the stu1 object to "Li Si", and both Citation objects will show Li Si. This is the effect of shallow cloning, which copies the attributes of the reference type in the specific prototype class (Citation).
This scenario requires deep cloning, while deep cloning requires object flow.
The code is as follows:
public class CitationTest1 { public static void main(String[] args) throws Exception { Citation c1 = new Citation(); Student stu = new Student("Zhang San", "Xi'an"); c1.setStu(stu); //Create Object Output Stream Object ObjectOutputStream oos = new ObjectOutputStream(newFileOutputStream("C:\\Users\\Think\\Desktop\\b.txt")); //Write out c1 objects to a file oos.writeObject(c1); oos.close(); //Create Object Outflow Object ObjectInputStream ois = new ObjectInputStream(newFileInputStream("C:\\Users\\Think\\Desktop\\b.txt")); //read object Citation c2 = (Citation) ois.readObject(); //Student to whom the c2 Award is awarded Student stu1 = c2.getStu(); stu1.setName("Li Si"); //Determine if stu object and stu1 object are the same object System.out.println("stu and stu1 Is it the same object?" + (stu == stu1)); c1.show(); c2.show(); } }
Result:
Note: The Citation and Student classes must implement the Serializable interface, or the NotSerializableException exception will be thrown.