编程知识 cdmana.com

Prototype pattern of Java design pattern

The definition of prototype patterns :

   A prototype pattern refers to a prototype instance that specifies the type of object to be created , And create new objects by copying these prototypes , It belongs to the creative design pattern . The core of the prototype pattern is to replicate the prototype object .

With an object prototype that already exists in the system , Copy directly from memory binary stream , No need to go through the time-consuming process of object initialization , Performance will be greatly improved .

Application scenario of prototype mode :

  • It costs a lot to create objects , Need to optimize resources .
  • Creating an object requires tedious data preparation or permission access , Need to improve performance or security .
  • This kind of object is widely used in the system , And each caller needs to reassign its properties .

analysis JDK Shallow clone API The problems brought about by :

   stay java Provided API in , There is no need to manually create an abstract prototype interface ,java Built in Cloneable Abstract prototype interface , Custom types only need to implement the interface and override Object.clone The method can be completed

A reproduction of this class .

   By looking at JDK Source code discovery for , Actually Cloneable Is an empty interface .java The reason for offering Cloneable Interface , Just to notify at run time java Virtual machines can be safely used on this class clone

Method . If not Cloneable Interface , call clone() Method will throw CloneNotSupportedException abnormal .

 

  If you use clone() Method , The following conditions need to be met :

  1. For any object o, There are o.clone() != o, In other words, the cloned object and the original object are not the same object .
  2. For any object o, There are o.clone().getClass() == o.getClass(), In other words, the cloned object is of the same type as the original object .
  3. For any object o, Should have o.clone().equals(o) establish , Why is this not absolute , Because if you don't rewrite hashcode and equals Under the circumstances , There is no guarantee of two objects equals equal .

So in java What's the problem with medium to shallow cloning , See the following example :

Create a User class , And rewrite clone Method :

package com.liuyi.designmode.creational.prototype;

import lombok.Data;

import java.util.List;

/**
 * @ClassName User
 * @description:
 * @author:liuyi
 * @Date:2020/11/11 20:55
 */
@Data
public class User implements Cloneable{
    private Integer id;

    private String name;

    private List<String> phoneList;

    /* *
     * @Author liuyi
     * @Description //TODO  Rewrite the shallow cloning method 
     * @Date 2020/11/11 21:11 
     * @Param []
     * @return com.liuyi.designmode.creational.prototype.User
     **/
    @Override
    protected User clone(){
        try {
            return (User) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Create an object , And then clone an object , Then modify the corresponding attribute value :

package com.liuyi.designmode.creational.prototype;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName PrototypeTest
 * @description:
 * @author:liuyi
 * @Date:2020/11/11 21:04
 */
public class PrototypeTest {
    public static void main(String[] args) {
        // Create objects 
        User user = new User();
        user.setId(1);
        user.setName(" that ");
        List<String> PhoneList = new ArrayList<>();
        PhoneList.add("1457697");
        PhoneList.add("545452");
        PhoneList.add("5155445645");
        user.setPhoneList(PhoneList);
        // Print the previous object information 
        System.out.println(user);
        // Clone objects 
        User clone = user.clone();
        // modify id by 2
        clone.setId(2);
        // Delete list A value of the object 
        clone.getPhoneList().remove(1);
        // Print respectively 
        System.out.println(user);
        System.out.println(clone);

    }
}

Let's look at the execution results :

 

  You can see , I modified the cloned values , Basic data type id Changed the , It doesn't affect the original object , But change the reference type List, Then the value of the original object is changed . This is called shallow copy , This is also

The deadliest problem with shallow cloning . So how to solve this problem , Deep cloning can solve this problem .

Deep cloning using serialization :

   Add a deepClone() Method , The code is as follows :

 /* *
     * @Author liuyi
     * @Description  A deep clone 
     * @Date 2020/11/11 21:40 
     * @Param []
     * @return com.liuyi.designmode.creational.prototype.User
     **/
    public User deepClone(){
        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 (User)ois.readObject();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

hold clone Method modified to deepClone The results of this method are as follows :

 

  This modification does not affect the original object , We have achieved our goal .

Advantages of prototype pattern :

  • java The built-in prototype pattern is based on the replication of memory binary streams , In terms of performance, it is more direct than new One object is better .
  • You can use deep cloning to save the state of an object , To use when needed , For example, the history of restoration, a certain state , Can assist in undo operations .

Disadvantages of the prototype pattern :

  • You need to override clone Method to achieve .
  • clone Inside the class , Modify if necessary , You need to modify the code , Against the principle of opening and closing .
  • When it comes to deep cloning , You need to write complex code , And when objects are nested multiple times , Deep cloning is required for every layer of objects , It's more difficult to realize .

 

版权声明
本文为[A calf carrying a load]所创,转载请带上原文链接,感谢

Scroll to Top