The creation of Java design patterns prototype pattern

First, what is the [prototype mode] :

The prototype pattern is mainly used for the creation of objects, using prototype instances to specify the types of objects to be created, and creating new objects by copying these prototypes. The UML class diagram is as follows:

The core of the prototype pattern is the prototype class Prototype. The prototype class needs to meet the following two conditions:

  • (1) Implementing the Cloneable interface: The function of the Cloneable interface in Java is to notify the virtual machine at runtime that the clone() method can be safely used on the class that implements the Cloneable interface. Only the class that implements the Cloneable interface can be copied. Otherwise a CloneNotSupportedException will be thrown at runtime.
  • (2) Override the clone() method in the Object class: The parent class of all classes in Java is Object, and there is a clone() method in Object that returns a copy of the object, but its scope is protected, and general classes cannot call, therefore, the Prototype class needs to change the scope of the clone() method to public.

The prototype pattern is a relatively simple pattern, and it is also very easy to understand. Implementing an interface and overriding a method completes the prototype pattern. In practical applications, the prototype pattern rarely appears alone. Often mixed with other patterns, his prototype class Prototype is often replaced by abstract classes.        

Second, the advantages and applicable scenarios of the prototype mode:

(1) The performance of the prototype mode is much better than that of the new method, because the clone() method of the Object class is a local method, which directly operates the binary stream in the memory, especially when copying large objects, the performance difference is very obvious;

(2) Simplify the creation of objects;

Therefore, the prototype mode is suitable for use in scenarios where similar objects are repeatedly created, such as creating objects in a loop. If the object creation process is complex or the number of loops is large, using the prototype mode can not only simplify the creation process, but also provide the overall system performance.

3. Matters needing attention:

(1) Copying an object using prototype mode does not call the constructor of the class. The object is done by calling the clone() method of the Object class, which directly copies data in memory. Not only will the constructor not execute, but even the access rights are invalid for prototype mode. In the singleton mode, you need to set the access permission of the constructor to private, but the clone() method directly ignores the permission of the constructor, so the singleton mode and the prototype mode are in conflict, and you need to pay attention when using them.

(2) Deep copy and shallow copy. The clone() method of the Object class will only copy the basic data types in the object (8 basic data types byte, char, short, int, long, float, double, boolean and corresponding encapsulation classes), for arrays, container objects , reference objects, etc. will not be copied, which is a shallow copy. If you want to implement deep copying, you must copy the arrays, container objects, reference objects, etc. in the prototype mode separately.

  • Shallow copy: Only the basic data types in the object are cloned, not arrays, containers, reference objects, etc. In other words, a shallow copy only copies the object in question, not the object it refers to. If the variable is a String string, copy its reference address, but when it is modified, it will regenerate a new string from the string pool, and the original string object remains unchanged.
  • Deep copy: The objects referenced by the object to be cloned are cloned.

For more information about deep copy and shallow copy, you can refer to this article: Java Basics: Object Copy: clone method and serialization_Zhang Weipeng’s blog – CSDN Blog

Fourth, the implementation code:

public abstract class Prototype implements Cloneable {
    protected ArrayList<String> list = new ArrayList<String>();

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public abstract void show();
}

public class ShallowClone extends Prototype {
    @Override
    public Prototype clone(){
        Prototype prototype = null;
        try {
            prototype = (Prototype)super.clone();
        }
        catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return prototype;
    }

    @Override
    public void show(){
        System.out.println( "Shallow clone" );
    }
}

public class DeepClone extends Prototype {
    @SuppressWarnings("unchecked")
    @Override
    public Prototype clone() {
        Prototype prototype = null;
        try {
            prototype = (Prototype)super.clone();
        }
        catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        prototype.list = (ArrayList<String>) this.list.clone();
        return prototype;
    }

    @Override
    public void show(){
        System.out.println( "deep clone" );
    }
}

Since ArrayList is not a basic type, the member variable list will not be copied, and we need to implement deep copy by ourselves. Fortunately, most of the container classes provided by Java implement the Cloneable interface. So implementing a deep copy is not particularly difficult.

public class Client {
    public static void main(String[] args) {
        ShallowClone cp = new ShallowClone();
        ShallowClone clonecp = (ShallowClone) cp.clone();
        clonecp.show();
        System.out.println(clonecp.list == cp.list);

        DeepClone cp2 = new DeepClone();
        DeepClone clonecp2 = (DeepClone) cp2.clone();
        clonecp2.show();
        System.out.println(clonecp2.list == cp2.list);
    }
}

operation result:

shallow clone 
true 
deep clone 
false

[Design Patterns] series of articles:

Creation of Java Design Patterns: Detailed Explanation of Factory Patterns (Simple Factory + Factory Method + Abstract Factory)

The creation of Java design patterns: the builder pattern

The creation of Java design patterns: the singleton pattern

The creation type of Java design pattern: prototype pattern

Structural Types of Java Design Patterns: Adapter Patterns

Structural Types of Java Design Patterns: Decorator Patterns

The Structural Type of Java Design Patterns: The Proxy Pattern

Structural Types of Java Design Patterns: Bridge Patterns

Structural Types of Java Design Patterns: Facade Patterns

Structural Types of Java Design Patterns: Composition Patterns

Structural Types of Java Design Patterns: Flyweight Pattern

Behavioral Types of Java Design Patterns: Strategy Patterns

Behavioral Types of Java Design Patterns: Template Method Pattern

Behavioral Types of Java Design Patterns: The Chain of Responsibility Pattern

Behavioural of Java Design Patterns: Observer Pattern

Behavioral Types of Java Design Patterns: The Visitor Pattern

Behavioral Types of Java Design Patterns: The Mediator Pattern

Behavioral Types of Java Design Patterns: Command Patterns

Behavioral Types of Java Design Patterns: State Patterns

Behavioral Types of Java Design Patterns: The Memento Pattern

Behavioral Types of Java Design Patterns: The Iterator Pattern

Behavioral Types of Java Design Patterns: Interpreter Patterns

Original blog link:

[The Prototype Mode of JAVA Design Patterns]

Design Patterns – Creation – Prototype Patterns (Prototype) – vapy’s blog – CSDN Blog

Leave a Comment

Your email address will not be published. Required fields are marked *