Design pattern - prototype pattern

Keywords: Java Design Pattern

definition

Using an instance that has been created as a prototype, create a new object that is the same as the prototype object by copying the prototype object.

Role and class diagram of pattern

The prototype pattern contains the following roles:

  • Abstract prototype class: Specifies the clone() method that the concrete prototype object must implement.
  • Concrete prototype class: implement the clone() method of the Abstract prototype class, which is an object that can be copied.
  • Access class: use the clone() method in the concrete prototype class to copy the new object.

Class diagram

Cloneable interface is just an identifier. There are no methods in the interface. The real clone method is in the Object class.

realization

The specific codes are as follows:

public class User implements Cloneable, Serializable {
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public User(){
        System.out.println("Prototype object creation completed");
    }
    @Override
    protected User clone() throws CloneNotSupportedException {
        return (User)super.clone();
    }
    public void show(){
        System.out.println("user"+person.getName()+"I am working!");
    }
}
public class Person implements Serializable {
    private String name;

    public Person(String name){
        this.name = name;
    }

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

    public String getName() {
        return name;
    }
}

Test with test code:

public class MainTest {
    public static void main(String[] args) throws Exception {
        User user = new User();
        Person person = new Person("Zhang San");
        user.setPerson(person);
        User user1 = user.clone();
        System.out.println(user1 == user);
        System.out.println(user1.getPerson() == user.getPerson());
    }
}

result:

Prototype object creation completed
false
true

Therefore, the object obtained by using the cloning method in Obeject is a new object. However, the non basic type properties in the object are equal and are not recreated. This leads to deep and shallow copies of prototype patterns.

Light copy and deep copy

definition

  • Shallow cloning: create a new object. The properties of the new object are exactly the same as the original object. For non basic type properties, it still points to the memory address of the object pointed to by the original property.
  • Deep clone: when a new object is created, other objects referenced in the attribute will also be cloned and no longer point to the original object address.

Therefore, if you only implement the clone method in the Object and do not override it, it is a shallow copy, and the non basic type attributes in the Object do not recreate a new Object. If you need a new property Object. You can override the clone method. Create a new property Object. This is the deep copy.
If deep copy is implemented, the clone method can be rewritten. The specific code is as follows:

 @Override
    protected User clone() throws CloneNotSupportedException {
        User user = (User)super.clone();
        user.setPerson(new Person("New object"));
        return user;
    }

Test results:

Prototype object creation completed
false
false

Another kind of deep copy is to read the objects written to the file through the object stream. In single column mode, we talk about the destruction of single column mode by object flow. Without the readrestore method, when the object stream reads the object, it will return a new object, which is a deep copy object. We passed the code test.
The specific codes are as follows:

public class MainTest {
    public static void main(String[] args) throws Exception {
        User user = new User();
        Person person = new Person("Zhang San");
        user.setPerson(person);


        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\lenovo\\Desktop\\cs.txt"));
        oos.writeObject(user);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\lenovo\\Desktop\\cs.txt"));
        User user1 = (User)(ois.readObject());
        ois.close();

        System.out.println(user.getPerson() == user1.getPerson());
        user.show();
        user1.getPerson().setName("Li Si");
        user1.show();


    }
}

result:

Prototype object creation completed
false
User Zhang San is working!
User Li Si is working!

The above code does not call the clone method. Through the readObject() of the object stream, we get the result that the prototype object is created and the non basic type attributes are recreated. This is the deep copy.

Posted by katie77 on Wed, 06 Oct 2021 18:08:28 -0700