This is the 9th day of my participation in the August Wen Challenge.More challenges in August

In Dr. Yan Hong’s book “JAVA and Pattern”, the beginning of the Prototype mode is described as follows: Prototype mode belongs to the object creation mode. Specify the types of all created objects by giving a prototype object, and then create more objects of the same type by copying that prototype object. This is the purpose of the model selection.

The prototype pattern is the creation pattern, which creates a new object through new and then invokes the operations related to the object. The prototype pattern provides the Clone method with copy-ability to quickly create an object, which can be quickly created when creating complex objects.

Usage scenarios for prototype patterns

  1. When creating a class consumes a lot of resources, such as initializing a lot of data or occupying too much hardware resources, we can avoid these costs by copying the prototype.
  2. When a class object needs to be shared; Because each caller may modify the operation object, consider copying multiple objects in prototype mode.
  3. If generating an object from New requires very tedious data preparation or access rights, you can use the prototype pattern.

A UML diagram of the stereotype pattern

Role of

  • Abstract Prototype Interface (IPrototype) : Defines a clone – capable set of interface standards.
  • ConcreteProtoType: a ConcreteProtoType class that implements an abstract prototype interface.
  • Client: indicates the client user.

Case Scenario Here assumes that there is an archive, which has many administrators who can view and manage student information at any time and add student contact information.

Define the prototype interface and concrete interface implementation classes

/** * define a clone - capable abstract interface *@author Iflytek_dsw
 *
 */
abstract class Prototype {
	protected String name;
	protected ArrayList<String> telephoneList;
	
	public Prototype(String name){
		this.name = name;
		telephoneList = new ArrayList<>();
	}
	
	public void addTelephone(String telephone){
		telephoneList.add(telephone);
	}
	
	public void printTele(a){
		for(String tele : telephoneList){ System.out.println(tele); }}// Interface with clone capability
	public abstract Prototype clone(a);
}

/** * concrete implementation class, *@author Iflytek_dsw
 *
 */
class StudentPrototype extends Prototype{

	public StudentPrototype(String name) {
		super(name);
	}

	@Override
	public Prototype clone(a) {
		StudentPrototype prototype = new StudentPrototype(name);
		prototype.name = name;
		prototype.telephoneList = telephoneList;
		returnprototype; }}/** * Concrete prototype implementation class *@author Iflytek_dsw
 *
 */
class TeacherPrototype extends Prototype{

	public TeacherPrototype(String name) {
		super(name);
	}

	@Override
	public Prototype clone(a) {
		TeacherPrototype prototype = new TeacherPrototype(name);
		prototype.name = name;
		prototype.telephoneList = telephoneList;
		returnprototype; }}Copy the code

Define client usage

public class Client {

	/ * * *@param args
	 */
	public static void main(String[] args) {
		Prototype prototype = new StudentPrototype("Xiao li");
		prototype.addTelephone("152000000");
		prototype.addTelephone("152111111");
		System.out.println("Primitive type value:");
		prototype.printTele();
		
		Prototype prototypeClone = prototype.clone();
		prototypeClone.addTelephone("1530000");
		System.out.println("Clone type value:");
		prototypeClone.printTele();
		
		System.out.println("Original type modified value:"); prototype.printTele(); }}Copy the code

Let’s take a look at the specific results:

Original type: 152000000 152111111 Clone type: 152000000 152111111 1530000 Original type: 152000000 152111111 1530000Copy the code

As can be seen from the above, the value of the clone object will respond to its prototype after the operation. In some cases this approach destroys the prototype data. In the clone method above, we assign the telephoneList variable directly to the cloned object. In essence, the telephoneList of the cloned object is just a reference to the prototype. We do not recreate it by new. Therefore, telephoneList has only one address in memory, and the copy and prototype are common. Therefore, operations between copies will affect the prototype. This approach is called “shallow copy”.

Prototype pattern is a very simple pattern in the design pattern, its core problem is about the clone method to Copy the original Object, Object Copy is to Copy the attributes of an Object to another Object with the same class type. It is common to copy an object in a program, mainly to reuse some or all of the object’s data in a new context. Note that there are two copy modes: shallow copy and deep copy.

Shallow copy and deep copy

Shallow copy A shallow copy is a bitwise copy of an object. It creates a new object with an exact copy of the original object’s property values. If the attribute is of a primitive type (such as a primitive data type, String), the value of the primitive type is copied. If the property is a memory address (reference type, object), the memory address is copied, so if one object changes the address, the other object will be affected. Common ways:

  • Variables are assigned directly

Deep copy The deep copy copies all attributes and the dynamically allocated memory that the attributes point to. Deep copy occurs when an object is copied along with the object it references. Deep copy is slower and more expensive than shallow copy. Common implementations:

  • Create new objects of class and member variables with new;
  • Deep copy is implemented by serialization, which writes the entire object graph to a persistent storage file and reads it back when needed, which means that when you need to read it back you need a copy of the entire object graph. This is what you really need when you deeply copy an object. Note that when you do deep copy through serialization, you must ensure that all classes in the object graph are serializable. This method of serialization has its own limitations and problems: 1. Transient variables cannot be serialized, and transient variables cannot be copied using this method. Too wasteful of efficiency and too slow.

In Java, all classes integrate with Object. The Object class provides a protected Object Clone () method for copying objects. Subclasses can also replace this method. Provide replication methods that meet your needs. One of the basic problems with object copying is that objects often have references to other objects. When you copy an Object using the Clone () method of the Object class, its references to other objects are also copied

The Cloneable interface provided by the Java language only notifies the Java virtual machine at run time that it is safe to use the Clone () method on this class. A copy of an object can be obtained by calling the clone() method. Because the Object class itself doesn’t implement Cloneable interface, so if the class does not implement the Cloneable interface, call clone () method will throw CloneNotSupportedException anomalies.

Cloning meets the conditions

The clone() method makes a copy of the object and returns it to the caller. What is meant by “copy” and how the Clone () method is implemented. In general, the Clone () method satisfies the following description:

  1. For any object x, there is: x.lone ()! = x. In other words, the cloned object is not the same object as the original object.
  2. For any object x, there is x.lone ().getClass() == x.getclass (). In other words, the cloned object is of the same type as the original object.
  3. X.lone ().equals(x) should be true if the equals() method of object X defines it properly.

All classes in the JAVA language API that provide the Clone () method satisfy these conditions. JAVA language designers should also follow three conditions when designing their Clone () methods. In general, the first two of the above three conditions are required, while the third is optional.

conclusion

Advantages: The prototype pattern allows specific implementation types to be dynamically changed at run time. The prototype pattern allows the client to register an implementation type that matches the prototype interface at run time, or to dynamically change the specific implementation type so that the interface appears unchanged but is actually running another class instance. Because cloning a prototype is similar to instantiating a class.

Disadvantages of the prototype pattern: The primary disadvantage of the prototype pattern is that each class must be equipped with a clone method. Having a clone approach requires a thorough consideration of the functionality of a class, which is not difficult for a new class, but not always easy for an existing class, especially if a class references indirect objects that do not support serialization, or references that have a circular structure.

So what if the scenario above was changed to: Everyone can view the backup file, but the prototype is not affected by the copy? ^ – ^.