Design Mode: Study Notes (7) - Prototype Mode

Design Mode: Study Notes (7) - Prototype Mode

quick start

introduce

  The Prototype Pattern is used to create repetitive objects while maintaining performance . This type of design pattern is a creational pattern, which provides an optimal way to create objects.

  This pattern implements a prototype interface that is used to create a clone of the current object. This mode is used when the cost of directly creating the object is relatively high . For example, an object needs to be created after an expensive database operation. We can reduce database calls by caching the object, returning a clone of it on the next request, and updating the database when needed.

  We all know that cloning is to use one object to copy several identical objects. Similarly, in object-oriented systems, we can also use cloning technology to clone several identical objects. In the application, some objects are more complicated, the creation process is too complicated, and we need to use the object frequently. If we new the object according to the conventional thinking at this time, it must bring a lot of trouble. At this time, we Just hope that you can use an existing object to continuously copy it, which is the "clone" in programming. Here the prototype pattern can satisfy our "clone". In the prototype pattern, we can use a prototype object to indicate the type of object we want to create, and then obtain the exact same object instance by copying the object. That's what the prototype pattern was designed for.

  After seeing this and thinking about it, I have a certain understanding of the prototype pattern: we may have created a complex object with a lot of effort, and now we want several other objects that are almost the same as this one, we Instead of new, we directly use the deep copy provided by Java to copy the object.

Pattern Principle

  We all know that Object is the ancestor, all Java classes inherit from Object, and the Object class provides a clone() method, which can copy a java object, so you can use the clone() method directly in java to Copy an object. However , the Java class that needs to implement clone must implement an interface: Cloneable. This interface represents the ability of the class to be copied and specifically copied. If the clone() method is called directly without implementing this interface, a CloneNotSupportedException will be thrown . as follows:

public class PrototypeDemo implements Cloneable{
  public Object clone(){
    Object object = null;
    try {
      object = super.clone();
    } catch (CloneNotSupportedException exception) {
      System.err.println("Not support cloneable");
    }
    return object;
    }
    ……
}

 Any class in Java that implements the Cloneable interface can make a copy of itself and pass it to the caller by calling the clone() method. In general, the clone() method satisfies: 
      (1) For any object x, there is x.clone() !=x, that is, the cloned object and the original object are not the same object. 
      (2) For any object x, there is x.clone().getClass()==x.getClass(), that is, the cloned object has the same type as the original object. 
      (3) If the equals() method of the object x is properly defined, then x.clone().equals(x) should hold.

Case Analysis

You should have done copying your resume! Here we use the prototype mode to simulate copying resumes.

      Resume: Resume.java 

public class Resume implements Cloneable {
    private String name;
    private String birthday;
    private String sex;
    private String school;
    private String timeArea;
    private String company;
    
    /**
     * Constructor: Initialize resume assignment name
     */
    public Resume(String name){
        this.name = name;
    }
    
    /**
     * @desc set personal basic information
     * @param birthday birthday
     * @param sex gender
     * @param school graduate school
     * @return void
     */
    public void setPersonInfo(String birthday,String sex,String school){
        this.birthday = birthday;
        this.sex = sex;
        this.school = school;
    }
    
    /**
     * @desc set work experience
     * @param timeArea working years
     * @param company company
     * @return void
     */
    public void setWorkExperience(String timeArea,String company){
        this.timeArea = timeArea;
        this.company = company;
    }
    
    /**
     * clone the instance
     */
    public Object clone(){
        Resume resume = null;
        try {
            resume = (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace ();
        }
        return resume;
    }
    
    public void display(){
        System.out.println("姓名:" + name);
        System.out.println("birthday: " + birthday + ", gender: " + sex + ", graduation school: " + school);
        System.out.println("Working years: " + timeArea + ", company: " + company);
    }

      Client: Client.java

public class Client {
    public static void main(String[] args) {
        //Prototype A object
        Resume a = new Resume("Little plum");
        a.setPersonInfo("2.16", "男", "XX大学");
        a.setWorkExperience("2012.09.05", "XX Technology Co., Ltd.");
        
        //Clone the B object
        Resume b = (Resume) a.clone();
        
        // output A and B objects
        System.out.println("----------------A--------------");
        a.display();
        System.out.println("----------------B--------------");
        b.display();
        
        /*
         * Test A==B?
         * For any object x, there is x.clone() !=x, that is, the cloned object is not the same object as the original object
         */
        System.out.print("A==B?");
        System.out.println( a == b);
        
        /*
         * For any object x, there is x.clone().getClass()==x.getClass(), that is, the cloned object has the same type as the original object.
         */
        System.out.print("A.getClass()==B.getClass()?");
        System.out.println(a.getClass() == b.getClass());
    }
}

Why use Super.clone()

  1. When the clone in the Object is executed, the RTTI (run-time type identification) mechanism is used. It dynamically finds the reference that is currently calling the clone method, applies for memory space according to its size, and then performs bitwise copying. The memory space of the object is completely copied to the new space, so as to achieve the purpose of shallowcopy. So when you call super.clone() you get a copy of the currently calling class, not a copy of the parent class. There is no need to call this.clone();
  2. To make an instance call the clone method, you need to make this class implement the Cloneable interface. There is also a sentence in the API: if you call the clone method of Object on an instance that does not implement the Cloneable interface, will result in a CloneNotSupportedException being thrown, which is what "legal" means. But please note that the Cloneable interface is just a label interface and does not have any methods to implement, just like the Serializable interface.
In short, if your subclass has no special needs and overrides the clone() method, just use super.clone() directly .

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325499198&siteId=291194637