Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

An overview of the

Using an already created instance as a prototype, create a new object that is identical to the prototype object by copying the prototype object.

structure

The archetypal pattern contains the following characters:

  • Abstract stereotype classes: Clone () methods that specify the concrete stereotype objects that must be implemented.
  • Concrete stereotype class: The Clone () method that implements the abstract stereotype class, which is an object that can be copied.
  • Access classes: Copy new objects using the clone() method in the concrete prototype class.

The interface class diagram is as follows:

implementation

The clone of prototype mode is divided into shallow clone and deep clone.

Shallow clone: Create a new object with the same attributes as the original object. For non-basic attributes, the new object still points to the memory address of the object pointed to by the original attribute.

Clone: When a new object is created, other objects referenced in the property will also be cloned, instead of pointing to the original object address.

The Clone () method is provided in the Object class in Java to implement shallow cloning. The Cloneable interface is the abstract prototype class in the class diagram above, and the child implementation class that implements the Cloneable interface is the concrete prototype class. The code is as follows:

Realizetype (concrete prototype class) :

public class Realizetype implements Cloneable {

    public Realizetype(a) {
        System.out.println("Concrete prototype object created!");
    }

    @Override
    protected Realizetype clone(a) throws CloneNotSupportedException {
        System.out.println("Concrete prototype copied successfully!");
        return (Realizetype) super.clone(); }}Copy the code

PrototypeTest (test access class) :

public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Realizetype r1 = new Realizetype();
        Realizetype r2 = r1.clone();

        System.out.println("Are objects R1 and R2 the same object?"+ (r1 == r2)); }}Copy the code

case

Generate “Merit Student” awards with prototype mode

The “merit Student” certificates of the same school are all the same except for the different names of the recipients. You can use the prototype mode to copy multiple “merit Student” certificates, and then modify the names on the certificates.

The class diagram is as follows:

The code is as follows:

/ / diploma classes
public class Citation implements Cloneable {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName(a) {
        return (this.name);
    }

    public void show(a) {
        System.out.println(name + Classmate: I performed well in the first semester of the 2020 academic year and was awarded "Merit Student". Especially so!");
    }

    @Override
    public Citation clone(a) throws CloneNotSupportedException {
        return (Citation) super.clone(); }}// Test access classes
public class CitationTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation c1 = new Citation();
        c1.setName("Zhang");

        // Copy the certificate
        Citation c2 = c1.clone();
        // Change the name of the certificate to Li Si
        c2.setName("Bill"); c1.show(); c2.show(); }}Copy the code

Usage scenarios

  • Object creation is very complex, and you can use prototype mode to create objects quickly.
  • High performance and safety requirements.

Extension (hyperclone)

Change the name attribute of the Citation class to a Student attribute. The code is as follows:

/ / diploma classes
public class Citation implements Cloneable {
    private Student stu;

    public Student getStu(a) {
        return stu;
    }

    public void setStu(Student stu) {
        this.stu = stu;
    }

    void show(a) {
        System.out.println(stu.getName() + Classmate: I performed well in the first semester of the 2020 academic year and was awarded "Merit Student". Especially so!");
    }

    @Override
    public Citation clone(a) throws CloneNotSupportedException {
        return (Citation) super.clone(); }}/ / class students
public class Student {
    private String name;
    private String address;

    public Student(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public Student(a) {}public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress(a) {
        return address;
    }

    public void setAddress(String address) {
        this.address = address; }}/ / test class
public class CitationTest {
    public static void main(String[] args) throws CloneNotSupportedException {

        Citation c1 = new Citation();
        Student stu = new Student("Zhang"."Xi 'an");
        c1.setStu(stu);

        // Copy the certificate
        Citation c2 = c1.clone();
        // Get the c2 certificate for the student
        Student stu1 = c2.getStu();
        stu1.setName("Bill");

        // Check whether stu and STU1 are the same object
        System.out.println("Stu and STU1 are the same object?"+ (stu == stu1)); c1.show(); c2.show(); }}Copy the code

The running results are as follows:

Stu1; stu1; stU; stu1; stU; stu1 This is the effect of shallow cloning, copying the attributes of a reference type in a concrete prototype class (Citation). This situation requires the use of deep cloning, which requires the use of object streams. 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"."Xi 'an");
        c1.setStu(stu);

        // Create an object output stream object
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt"));
        // Write the c1 object into the file
        oos.writeObject(c1);
        oos.close();

        // Create a stream object
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt"));
        // Read the object
        Citation c2 = (Citation) ois.readObject();
        // Get the c2 certificate for the student
        Student stu1 = c2.getStu();
        stu1.setName("Bill");

        // Check whether stu and STU1 are the same object
        System.out.println("Stu and STU1 are the same object?"+ (stu == stu1)); c1.show(); c2.show(); }}Copy the code

The running results are as follows:

Note: The Citation and Student classes must implement the Serializable interface, otherwise NotSerializableException will be thrown.