This is the fifth day of my participation in the First Challenge 2022

Take you through different prototype patterns

concept

Prototype Pattern refers to the type of objects created by Prototype instances and the creation of new objects by copying these prototypes. Ontology provides a clone for external use, which belongs to the creation Pattern in the process of class.

Application scenarios for the prototype pattern

  • Resource optimization can be performed when the initial loading of a class consumes too many resources

  • When there are special requirements for performance and security, such as access rights, new creates a cumbersome process in an object

  • One object corresponds to multiple modified scenarios

  • When an object needs to be made available to other objects, and each caller may need to modify its value, consider using the prototype pattern to copy multiple objects for use by the caller.

Shallow copy method

The core of the prototype pattern is copying objects. Take an object that already exists in the system as the prototype, directly give the binary memory of the object to copy, do not need to go through the initialization process of the object, do not need to call the constructor, can be directly copied after the direct use, and then optimize resources, can improve a lot of performance. Copies are generally classified into shallow copies and deep copies.

Shallow copy is the creation of a new object, obtained by bitcopy, that has an exact copy of the original object’s property values. If the property is of a primitive type, it copies the value of the primitive type. If the property is of a reference type, it copies the memory address, so if one object changes the address, it affects the other object.

Code implementation

  • ConcretePrototype
public class ConcretePrototype implements Cloneable {


    private Integer age;
    private String name;
    private List hobbies;

    @Override
    public ConcretePrototype clone(a) {

        try {
            return (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null; }}}Copy the code
  • test
public static void main(String[] args) {
    ConcretePrototype concretePrototype = new ConcretePrototype();
    concretePrototype.setAge(20);
    concretePrototype.setName("Zhang");
    List hobbies = new ArrayList();
    hobbies.add("Game");
    hobbies.add("Basketball");
    concretePrototype.setHobbies(hobbies);

    ConcretePrototype cloneType = concretePrototype.clone();
    cloneType.getHobbies().add("Technology");
cloneType.setName("Bill");
cloneType.setAge(30);
    System.out.println("Prototype object:" + concretePrototype);
    System.out.println("Clone object:" + cloneType);
    System.out.println(concretePrototype == cloneType);
    System.out.println("Hobby of prototype object:" + concretePrototype.getHobbies());
    System.out.println("Clone object's hobby:" + cloneType.getHobbies());
    System.out.println(concretePrototype.getHobbies() == cloneType.getHobbies());
}
Copy the code
  • The results of

In this example, the copied ConcretePrototype class implements the Clone () method of the Object class that implements the Clonable interface and rewrites it. In the test class, we declare a concretePrototype class, set the properties of age, name, hobbies, and so on, and then use the Clone method to get a new copy of cloneType. The cloneType class resets the properties of age and name. Changes to the age and name properties of the copy object cloneType do not affect the original object, but changes to the hobbies property of the reference object do affect the reference value of the original object.

  • Shallow copy of the schematic diagram

Deep copy method

Deep copy is a more complete method than shallow copy, which copies all the attributes of the original object and the dynamically allocated memory that the attributes point to. Deep copy occurs when an object is copied along with the object it references. Deep copy is slower and more expensive than shallow copy.

Code implementation

  • ConcretePrototype
public class ConcretePrototype implements Cloneable.Serializable {


    private Integer age;
    private String name;
    private List hobbies;

    @Override
    public ConcretePrototype clone(a) {

        try {
            return (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null; }}public ConcretePrototype deepCloneHobbies(a) {
        try {
            ConcretePrototype result = (ConcretePrototype) super.clone();
            result.hobbies = (List) ((ArrayList) result.hobbies).clone();
            return result;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null; }}public ConcretePrototype deepClone(a) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (ConcretePrototype) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null; }}Copy the code
  • MainTest
public static void main(String[] args) {
    // Create a prototype object
    ConcretePrototype prototype = new ConcretePrototype();
    prototype.setAge(18);
    prototype.setName("Tom");
    List<String> hobbies = new ArrayList<String>();
    hobbies.add("Calligraphy");
    hobbies.add("Fine arts");
    prototype.setHobbies(hobbies);

    // Copy the prototype object
    ConcretePrototype cloneType = prototype.deepCloneHobbies();
    cloneType.getHobbies().add("Technology control");
    System.out.println("Prototype object:" + prototype);
    System.out.println("Clone object:" + cloneType);
    System.out.println(prototype == cloneType);
    System.out.println("Hobby of prototype object:" + prototype.getHobbies());
    System.out.println("Clone object's hobby:" + cloneType.getHobbies());
    System.out.println(prototype.getHobbies() == cloneType.getHobbies());
}
Copy the code
  • The results of

In this example, the copied ConcretePrototype class implements the Clone () method of the Object class that implements the Clonable interface and rewrites it. In the test class, declare a concretePrototype class, and set the properties of Age, name, hobbies, etc. Then the clone method is used to obtain a new copy class cloneType. The cloneType copy class adds a value to the HobBites reference property. As can be seen from the result, cloneType makes a deep copy of concretePrototype. A deep copy adds a value to its own property and only changes its own reference value, not the original object’s reference value. Deep copy is a copy of both the base type value and the memory address of the reference type.

  • Deep copy basic schematics

Clone break singleton mode

If we have a deep copy of the prototype that is a singleton, then the deep copy will break the singleton. In fact, Spring has a very simple way to prevent the singleton from being broken. Either the singleton does not implement the Clenable interface, or the Clone method of Object is overridden and returns the singleton in the Clone method.

Pros and cons of prototyping

advantages

  • High performance. Using Java’s own prototype mode can be much smaller than the operation and resource consumption of a new object directly, which has a good improvement in performance.

  • The code flow is simple, the prototype mode copy simplifies the creation of the object process, can directly modify the value of the existing object instance, to achieve the purpose of object reuse, in order to be used in need (such as restore to a historical state), can assist the realization of the undo operation.

disadvantages

  • Each Object must override the Clone method of Object. Java provides Cloneable to indicate that the Object can be copied, but the clone method of Object must be overridden to be copied.

  • Because the Clone method is in the class, if changes are made to existing classes, methods in the class need to be modified, which violates the open and closed principle of the seven Principles of design pattern (for adding development, closed for modification).

  • In the implementation of deep cloning, complex code needs to be written, and when there are multiple nested references between objects, in order to achieve deep cloning, the corresponding classes of each layer of objects must support deep cloning, which is quite troublesome to implement. Therefore, deep copy and shallow copy need to be used properly.

conclusion

  • Copy the way

    • 1. Serialization Deserialization
    • 2.JsonObject
    • 3 Add assignment to shallow clone
  • Shallow copy

    All Cloneable interfaces are shallow clones.

  • A deep clone

    • serialization
    • Turn JSON