(Prototype Pattern)
(Prototype Pattern)
Creating a new object by copying, the caller does not need to know the creation details, does not call the constructor, is a creation pattern, in short, it is a clone of an object, use the scene
- Class initialization consumes too many resources
- Constructors are complex
- A large number of new objects are generated in the loop
There are two ways to write the prototype pattern, a shallow clone (the cloned object uses the same address) and a deep clone (the content of the cloned object is different),I mentioned this in [deep copy linked list with random pointers].
Shallow clone
@Data @ToString public class ConcretePrototype implements Cloneable { private int age; private String name; private List<String> hobbies; @Override protected ConcretePrototype clone() { try { return (ConcretePrototype) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
To test
public class Client { public static void main(String[] args) { ConcretePrototype concretePrototype=new ConcretePrototype(); concretePrototype.setAge(18); concretePrototype.setName("Glen"); List<String> hobbies=new ArrayList<String>(); hobbies.add("Girls"); hobbies.add("Techniques"); concretePrototype.setHobbies(hobbies); ConcretePrototype concretePrototype1=concretePrototype.clone(); concretePrototype1.getHobbies().add("man"); System.out.println(concretePrototype+"initial.."); System.out.println(concretePrototype1+"cloned.."); // They are different space of memory System.out.println(concretePrototype==concretePrototype1); // for primary data type can be pointed to different space of memory but specific type can not be (they remain point to the same space,such List) System.out.println(concretePrototype.getHobbies()==concretePrototype1.getHobbies()); } }
To explain:
apparently,for instance, They are different spaces,but for specific, They are same space,so according conclusion,we get that it use shallow clone in basis of jdk for specific type,actually jdk just copy value of address of memory, like value of 'int boolean、char、float、double' are saved in value of address of memory,but some specific types like List, in fact, their value of address of memory are saved their value of addres,so just copy their value of addres cause same scenario of value of addres.

Deep clone
method of serialization
@Data @ToString public class ConcretePrototype implements Cloneable,Serializable { private int age; private String name; private List<String> hobbies; ConcretePrototype deepClone() { ByteOutputStream byteOutputStream=new ByteOutputStream(); try { ObjectOutputStream objectOutput=new ObjectOutputStream(byteOutputStream); objectOutput.writeObject(this); ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteOutputStream.getBytes()); ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream); return (ConcretePrototype) objectInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } }
To test
public class Client { public static void main(String[] args) { ConcretePrototype concretePrototype=new ConcretePrototype(); concretePrototype.setAge(18); concretePrototype.setName("Glen"); List<String> hobbies=new ArrayList<String>(); hobbies.add("Girls"); hobbies.add("Techniques"); concretePrototype.setHobbies(hobbies); // We just replace the method of our cloning ConcretePrototype concretePrototype1=concretePrototype.deepClone(); concretePrototype1.getHobbies().add("man"); System.out.println(concretePrototype+"initial.."); System.out.println(concretePrototype1+"cloned.."); System.out.println(concretePrototype==concretePrototype1); System.out.println(concretePrototype.getHobbies()==concretePrototype1.getHobbies()); } }

To explain
We use serialization to create the classess, do you remember that we had mentioned the method in singleton (use serialization to destroy),so that we can not make a classess to be both singleton and prototype!! do you remember that if we override 'readResolve' what is the result, Right! The 'java.io.ObjectInputStream#readObject0' will not create the new classess, so we must not override 'readResolve'
Be applied into the souce of code
java.util.ArrayList#clone
java.util.HashMap#clone
We find out that resouce of code above both Override the 'java.lang.Object#clone' so can we Override that then add our logical code in it?definitely
ConcretePrototype deepCloneHobbies() { try { ConcretePrototype clone = (ConcretePrototype) super.clone(); clone.hobbies=(List)((ArrayList)clone.getHobbies()).clone(); return clone; } catch (Exception e) { e.printStackTrace(); } return null; }

Hi,we solve it perfectly,but if there are many specific type in the same class, do you want to do it more?so, personally, i think we use method of serialization more complete!
Sum up
advantage
- Be base on Binary stream to copy more efficient than to create a instance
- To simplify process of creating a class
disadvantage
we must add a method of clone in each classess in order to with clone to create classess




浙公网安备 33010602011771号