[Java Design Patterns] – Prototype Pattern

Hits: 0

💻 Profile

  • ⌨️ About the author: Hello everyone, I’m 〖Xue Yueqing〗 🌸
  • 🎉Personal homepage: [〖Xue Yueqing〗] ❄️
  • 📣Past Links: Singleton Pattern Factory Pattern

[prototype mode]

🏵️🏵️🏵️ Prototype Mode

🍊 1. Overview

Using an instance object that has been created as a prototype, copy a new object that is the same as the prototype. (Similar to 🤪 Yiqi Sanqing 🤪)

scenes to be used:

  • The creation of objects is very complicated, and the prototype mode can be used to quickly create objects
  • High performance and safety requirements

🍊 2. Structure

  • Abstract prototype class: defines the clone() method that a concrete prototype object must implement
  • Concrete prototype class: implements the clone() method of the abstract prototype class, which is a prototype class that can be copied
  • Access class: access the clone() method in the concrete prototype class to copy the new object (test class)

🍊 3. Implementation

Cloning in prototype mode is divided into shallow copy and deep copy

Shallow copy: The properties of the new object created are exactly the same as the original object. For non-basic type properties, its memory address still points to the memory address pointed to by the original object

Deep copy: the created new object properties and other objects referenced in the properties will also be cloned, no longer pointing to the original memory address

Note: Whether it is a shallow copy or a deep copy, a new object will be created, and the memory address of this object must be different from the original object! ! !

Similar to shortcuts and copy files on our computer

🌸 3.1 Shallow copy

🌰 1. Shallow copy implementation

The clone() method is provided in the Object class in Java to implement [shallow copy] method is provided in the Object class in Java to implement [shallow copy] . The Cloneable interface is an abstract prototype class** in the prototype pattern structure , and the sub-implementation class that implements the Cloneable interface is a concrete prototype class.[]

Cloneable interface:

The abstract prototype class is the Cloneable interface in the figure above

Concrete prototype class:

public class RealizeCopy implements Cloneable{
    public RealizeCopy(){
        System.out.println( "The concrete prototype object is created!" );
    }


    @Override
    protected RealizeCopy clone() throws CloneNotSupportedException {
        System.out.println( "Successful copy of the specific prototype!" );

        return (RealizeCopy) super.clone();
    }
}

Access class:

public  class  Client {
     public  static  void  main ( String[] args ) {
         //Create a prototype class object 
        RealizeCopy realizeCopy = new RealizeCopy();

        //Call the clone method in the RealizeCopy class to copy the object 
        try {
            RealizeCopy clone = realizeCopy.clone();

            //Compare the prototype object and the copied object System.out 
            .print ( " Prototype object vs copied object:" );
            System.out.println(realizeCopy== clone);

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }
}

operation result:

The new object copied by the shallow copy is the same as the original object, but the memory address is different, which is equivalent to renewing an object

🍉 2. The problem of shallow copy

Create a prototype object Study, which has a property of the student object

public class Study 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()+ "Start studying..." );
    }

    @Override
    protected Study clone() throws CloneNotSupportedException {
        return (Study) super.clone();
    }

}

Student class (the object referenced by the prototype object property)

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 + '\'' +
                '}';
    }
}

Access class:

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {

        //1. Create a prototype object 
        Study study1 = new Study();
         //Create a student object 
        Student student = new Student();
        student.setName( "Xue Yueqing" );
         //Assign the student object to the study1 object
        study1.setStudent(student);

        //2. Copy the study1 object
        Study study2 = study1.clone();
        study2.getStudent().setName( "Li Hua" );

        //3. Call the show() method
        study1.show();
        study2.show();

    }
}

operation result:

I was shocked to find that Li Hua turned out to be me! ! ! This is the problem of shallow copying, only one layer can be copied, that is, the prototype object itself, and the object referenced by the prototype object points to the same [memory] address, so whether study1 modifies the student or study2 modifies the student, it will cause The student property of both is changed.

This is a shallow copy of a non-primitive type attribute whose memory address still points to the memory address pointed to by the original object

Diagram:

🌸 3.2 Deep copy

The new object properties created and other objects referenced in the properties will also be cloned, no longer pointing to the original memory address

🌰 1. Implementation of deep copy

Deep copy using I/O streams

Prototype class (remember to implement Serializable interface)

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 + '\'' +
                '}';
    }
}

The prototype class attribute refers to the object class (remember to implement the Serializable interface)

public class Study 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()+ "Start studying..." );
    }

    @Override
    protected Study clone() throws CloneNotSupportedException {
        return (Study) super.clone();
    }

}

access class

public class Client {
    public static void main(String[] args) throws Exception {

        //1. Create a prototype object 
        Study study1 = new Study();
         //Create a student object 
        Student student = new Student();
        student.setName( "Xue Yueqing" );
         //Assign the student object to the study1 object
        study1.setStudent(student);

       //Create object output stream object 
        ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream( "d:/study.txt" ));
         //Write object
        oos.writeObject(study1);
        //close the resource
        oos.close();

        //Create object input stream object 
        ObjectInputStream ois = new ObjectInputStream( new FileInputStream( "d:/study.txt" ));
         //Read object
        Study study2 = (Study) ois.readObject();
        // release resources
        ois.close();

       study2.getStudent().setName( "Li Hua" );

       study1.show();
       study2.show();

    }
}

operation result:

Diagram:

If you like the article, you can support it three times! ! ! 💖💖💖

You may also like...

Leave a Reply

Your email address will not be published.