1 Introduction to prototype mode

A Prototype pattern is a created pattern. A Prototype pattern is a template instance with common information, and then copies the template instance. The copied instance is called a “Prototype”, and the Prototype can be modified. The prototype pattern is often used to create complex or time-consuming instances where copying an existing instance makes the program run more efficiently.

2. Prototype pattern definition

Specify what kind of objects to create with prototype instances, and create new objects by copying these prototypes

Prototype pattern UML class diagram

  • Client: Client role.
  • Prototype: Abstract stereotype role, abstract class or interface, used to declarecloneMethods.
  • ConcretePrototype: The concrete prototype class, which is the object used by the client role, that is, the object to be copied.

4 Usage scenarios of prototype patterns

  1. Class initialization consumes a lot of resources, including data, hardware resources, and so on. Avoid these costs by copying prototypes.
  2. throughnewGenerating an exclusivity requires very frequent data preparation or access rights.
  3. When an object needs to be made available to other objects, and each caller may need to modify its value, you can consider copying multiple objects for use by callers using the prototype pattern, known as protective copying.

5 Prototype mode Example

In this example, the Message class acts as ConcretePrototype, and Cloneable is the Prototype concrete class:

public class Message implements Cloneable{
    private String name;
    private double money;

    public Message() {
        System.out.println("Execute constructor Message");
    }

    public void setMessage(String name, double money) {
        this.name = name;
        this.money = money;
    }

    @NonNull
    @Override
    public Message clone() {
        Message message = null;
        try {
            message = (Message) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return message;
    }

    public void sendMessage(){
        System.out.println(name +"Hello: You have consumed today"+money+"Yuan"); }}Copy the code

The Message class implements the Cloneable interface, which is an identity interface that indicates that the object is copiable by overriding the Clone method.

It is important to note that the Clone method is not in the Cloneable interface, but in Object.

Let’s take a look at the client implementation:

public class MbClient {
    public static void main(String[] args){
        Message message = new Message();
        message.setMessage("Zhang", 100); Message message1 = message.clone(); message1.setMessage("Bill", 200); Message message2 = message.clone(); message2.setMessage("Fifty",300);

        message.sendMessage();
        message1.sendMessage();
        message2.sendMessage();
    }
}
Copy the code

We can see that the clone messages are cloned using the Clone method, which does not execute the constructor. The output is as follows:

// Execute constructor Message // Zhang SAN hello: you consumed 100.0 yuan today // Li Si hello: you consumed 200.0 yuan today // Wang Wu hello: you consumed 300.0 yuan todayCopy the code

If the Message class does not implement the Cloneable interface and calls the Clone method directly, an exception will be thrown. The following output is displayed:

Perform constructor Message Java. Lang. CloneNotSupportedException: com.monkey.myapplication.mbdemo.Message at java.lang.Object.clone(Native Method) at com.monkey.myapplication.mbdemo.Message.clone(Message.java:27) at com.monkey.myapplication.mbdemo.MbClient.main(MbClient.java:13) Exceptionin thread "main" java.lang.NullPointerException
	at com.monkey.myapplication.mbdemo.MbClient.main(MbClient.java:14)
Copy the code

6 Shallow copy and deep copy

Since the Clone method provided by the Object class does not copy internal arrays and reference objects in the Object, there are shallow and deep copies.

6.1 shallow copy

Moving on to the shallow copy example of sending a short Message, we have a consumption detail object in the Message class.

public class Message implements Cloneable{ private String name; // Private ExpenseDetail detail; // Consumption details publicMessage() {
        System.out.println("Execute constructor Message");
        detail = new ExpenseDetail();
    }

    public void setMessage(String name, String type,double money) {
        this.name = name;
        this.detail.setType(type);
        this.detail.setMoney(money);
    }

    @NonNull
    @Override
    public Message clone() {
        Message message = null;
        try {
            message = (Message) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return message;
    }

    public void sendMessage(){
        System.out.println(name +"Hello: You today"+detail.getType()+"Consumed"+detail.getMoney()+"Yuan"); }}Copy the code

Consumption Details class

public class ExpenseDetail{
    private String type;
    private double money;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) { this.money = money; }}Copy the code

The client class

public class MbClient {
    public static void main(String[] args){
        Message message = new Message();
        message.setMessage("Zhang"."Eat", 10); Message message1 = message.clone(); message1.setMessage("Bill"."Go to the movies", 50); Message message2 = message.clone(); message2.setMessage("Fifty"."Books",100);

        message.sendMessage();
        message1.sendMessage();
        message2.sendMessage();
    }
}
Copy the code

The output is as follows:

Execute the constructor Message Zhang SAN hello: you bought a book today to consume 100.0 yuan Li Si hello: you bought a book today to consume 100.0 yuan Wang Wu hello: you bought a book today to consume 100.0 yuanCopy the code

This is because the Clone method provided by the Object class does not copy the internal array and reference objects in the Object, so they still point to the internal element addresses of the original Object. This copy is called a shallow copy. This results in the last value overwriting the previous value.

6.2 deep copy

public class Message implements Cloneable{
    ...
    
    @NonNull
    @Override
    public Message clone() { Message message = null; try { message = (Message) super.clone(); message.detail = this.detail.clone(); / / copy statement} the catch (CloneNotSupportedException e) {e.p rintStackTrace (); }returnmessage; }... }Copy the code
public class ExpenseDetail implements Cloneable{
    private String type; private double money; . @NonNull @Override protected ExpenseDetailclone(){

        ExpenseDetail detail = null;
        try {
            detail = (ExpenseDetail) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        returndetail; }}Copy the code

When executed again using the shallow-copy client code, the output looks like this:

Li Si: You spent 50.0 yuan watching movies today. Wang Wu: You spent 100.0 yuan buying books todayCopy the code

Copy Message object at the same time, also copy its internal reference object ExpenseDetail, so that there is no association between each copy object, all point to its own corresponding ExpenseDetail, this copy is a deep copy.

7 summary

Archetypal patterns are essentially object copies. Using the prototype pattern can solve the resource consumption problem of building complex objects, can improve the efficiency of creating objects in some scenarios, and also has the feature of protective copy, if we operate, will not affect the original object.

Advantages: Prototype mode is a copy of the binary stream in memory, which is better than new an object, especially if you need to produce a large number of objects.

Disadvantages: copy directly in memory, constructors are not executed, this reduces constraints, both advantages and disadvantages, in real development should pay attention to this issue.