From the beginning of design patterns to learn Java architecture 3: Prototype Mode

Prototype model - refers to the specified type to create a prototype object instance, and create new objects by copying the prototype. The caller does not need to know any details of creating, not call the constructor ! It belongs create schema.

It is not through new, but already by the memory of the object as a template created without using the constructor of the way other objects.

There have been many prototype models of implementation, to beanutils, json, guava, achieve the JDK cloneable interfaces (the way to deep clone) and so on, do not care about their implementation, directly enough.

Divided into deep and shallow clone clone!

Shallow clone : Copy is a reference to the object, that is to say the value of the original object changes, then the value of the copied object will also change.

Deep Cloning : Copy the value of the object, by constructing bytecode out to create the object.

Wherein, Spring configuration is achieved by, generally shallow clone, also usually with mostly shallow clone.

It singleton pattern conflict. If every time you use an object to be created it, you can use the prototype model, if every time you can use the same object, you do not need to use the prototype model!

Example shallow clone -

Create a prototype Prototype Interface:

package com.pansoft.com.prototype;

public interface prototype {
    prototype clone();

}

 

Create a specific need to clone objects ConcretePrototype:

package com.pansoft.com.prototype;

import java.util.List;

public class ConcretePrototypeA implements prototype{
    private int age;
    private String name;
    private List hobbies;
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List getHobbies() {
        return hobbies;
    }

    public void setHobbies(List hobbies) {
        this.hobbies = hobbies;
    }

    public prototype clone(){
        ConcretePrototypeA concretePrototypeA = new ConcretePrototypeA();
        concretePrototypeA.setAge(this.age);
        concretePrototypeA.setName(this.name);
        concretePrototypeA.setHobbies(this.hobbies);
        return null;
    }

}

It inherits the Prototype Interface, big implements clone () method, new object in a ConcretePrototypeA clone method in class.

 

Creating Client object:

package com.pansoft.com.prototype;

public class Client {
    /*private prototype pro;
    public Client(prototype pro){
        this.pro = pro;
    }*/
    
    public prototype startClone(prototype concretePrototype){
        return concretePrototype.clone();
    }

}

In it through prototype interface object calls the clone method.

 

test:

package com.pansoft.com.prototype;

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

public class prototypeTest {
    public static void main(String[] args){
        ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
        concretePrototype.setAge(18);
        concretePrototype.setName("Tom");
        List hobbies = new ArrayList<String>();
        concretePrototype.setHobbies(hobbies);
        
        Client client = newClient (); 
        ConcretePrototypeA Copy = (ConcretePrototypeA) client.startClone (concretePrototype); 
        System.out.println (Copy); 
        
        System.out.println ( "clone object reference type address values:" + copy.getHobbies ()) ; 
        System.out.println ( "original object reference type address values:" + concretePrototype.getHobbies ()); 
        
        // equal, the value of copy is not described, but the address, which is shallow clone.
        // there are certain risks in this way 
        System.out.println ( "object address comparison:" + (copy.getHobbies () == concretePrototype.getHobbies ())); 
        
    } 

}

But the problem here is that the object clone () method was still by new methods and constructors to get in! I did not understand it ?

 

Example deep clone -

Create a prototype Monkey Monkey categories:

package com.pansoft.com.prototype.deep;

import java.util.Date;

public class Monkey {
    public int height;
    public int weight;
    public Date birthday;

}

It has three attributes, height, width and birthdays.

 

Create a reference object golden cudgel JinGuBang categories:

package com.pansoft.com.prototype.deep;

import java.io.Serializable;

public class JinGuBang implements Serializable {
    public float h = 100;
    public float d = 10;
    public void big(){
        this.d *= 2;
        this.h *= 2;
    }
    public void small(){
        this.d /= 2;
        this.h /= 2;
    }

}

It inherits Serializable interface defines two variables and initialization also defines two methods, one larger, a smaller.

 

Create specific objects Monkey King QiTianDaSheng categories:

package com.pansoft.com.prototype.deep;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class QiTianDaSheng extends Monkey implements Cloneable, Serializable {
    public JinGuBang jinGuBang;
    public QiTianDaSheng(){
        //只是初始化
        this.birthday = new Date();
        this.jinGuBang = new JinGuBang();
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException{
        return this.deepClone();
    }
    
    public Object 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);
            
            QiTianDaSheng copy = (QiTianDaSheng)ois.readObject();
            copy.birthday = new Date();
            return copy;
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
    
    public QiTianDaSheng shallowColne(QiTianDaSheng target){
        QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
        qiTianDaSheng.height = target.height;
        qiTianDaSheng.weight = target.weight;
        
        qiTianDaSheng.jinGuBang = target.jinGuBang; 
        qiTianDaSheng.birthday = new new a Date (); 
        
        return qiTianDaSheng; 
    } 

}

It inherits the class and Monkey Cloneable, Serializable interfaces, wherein the inside of the clone () method is a deep clone, shallowClone (QiTianDaSheng target) is shallow clone.

It was obtained by cloning in the deep embodiment to bytecode QiTianDaSheng object.

 

test:

Package com.pansoft.com.prototype.deep; 

public  class DeepCloneTest {
     public  static  void main (String [] args) { 
        QiTianDaSheng qiTianDaSheng = new new QiTianDaSheng ();
         the try { 
            QiTianDaSheng clone = (QiTianDaSheng) qiTianDaSheng.clone (); 
            the System. Out.println ( "deep clone:" + (qiTianDaSheng.jinGuBang == clone.jinGuBang)); 
        } the catch (Exception E) { 
            e.printStackTrace (); 
        } 
        
        QiTianDaSheng Q = new new QiTianDaSheng (); 
        QiTianDaSheng n- = q.shallowColne (Q); 
        System.out.println ( "shallow clone:" + (q.jinGuBang == n.jinGuBang)); 
    } 

}

Found deep cloned two objects are not equal, equal shallow clone. If the cloned depreciation means that the target object is a singleton object, so deep clone will destroy a single case, then how to prevent a single case of damage to deep clone it?

Either a singleton class does not implement Cloneable interface, or to keep the same section, the method override clone, clone returns singleton object to process - i.e. return INSTANCE;

 

We used ArrayList to achieve the Cloneable interface!

Guess you like

Origin www.cnblogs.com/yinyj/p/11266305.html