“This is the 22nd day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
Java prototype Pattern
Prototype patterns are used to create repetitive objects while maintaining performance. This type of design pattern is the creation pattern, which provides the best way to create objects.
This pattern implements a prototype interface that creates a clone of the current object. This pattern is used when the cost of creating objects directly is high. For example, an object needs to be created after an expensive database operation. We can cache the object, return a clone of it on the next request, and update the database as needed to reduce database calls.
introduce
Intent: Specify the type of object to create with prototype instances, and create new objects by copying these prototypes.
Main solution: create and delete prototypes at run time.
When to use:
⒈ When a system should be created, constructed, and expressed independently of its products.
⒉ When the class to be instantiated is specified at run time, for example, by dynamic loading.
⒊ Avoid creating a factory class hierarchy parallel to the product class hierarchy.
A. An instance of a class can have only one of several different state combinations. It may be more convenient to create a proportionate number of prototypes and clone them than to manually instantiate the class each time in the appropriate state.
How to solve this problem: Use an existing prototype object to quickly generate the same instance as the prototype object.
Key code:
⒈ Implement clone operation, inherit Cloneable in JAVA and rewrite clone(). In.NET, MemberwiseClone() method of Object class can be used to realize shallow copy of the Object or deep copy through serialization.
The ⒉ prototype pattern is also used to isolate the coupling between users of class objects and concrete types (mutable classes). It also requires these “mutable classes” to have stable interfaces.
Application examples:
⒈ Cell division.
⒉ The Object Clone () method in JAVA.
Advantages:
⒈ Improved performance.
⒉ Escaping the constructor constraint.
Disadvantages:
⒈ The allocation of clone methods requires a thorough consideration of the functions of classes, which is not difficult for new classes, but not necessarily easy for existing classes, especially when a class reference does not support serialized indirect objects, or references contain circular structures.
⒉ The Cloneable interface must be implemented.
Usage Scenarios:
⒈ Resources to optimize the scene.
Class ⒉ initialization needs to digest a lot of resources, including data, hardware resources, and so on.
⒊ performance and safety requirements.
It is possible to use prototype mode when producing an object through New requires very tedious data preparation or access rights.
A scenario where an object has multiple modifiers.
When a picture of an object needs to be made available to other objects and each caller may need to modify its value, you can consider using prototype mode to copy multiple objects for the caller to use.
In real projects, the prototype mode rarely appears alone. It usually appears with the factory method mode. It creates an object through the Clone method, and then the factory method provides it to the caller. The archetypal pattern has been integrated into Java and can be used at will.
Note: Instead of constructing a new object by instantiating a class, the prototype pattern generates a new object by copying an existing object. Shallow copy implements Cloneable, override, and deep copy reads binary streams by implementing Serializable.
implementation
We will create an abstract class Shape and an entity class that extends Shape. The next step is to define the ShapeCache class, which stores Shape objects in a Hashtable and returns clones of them on request.
PrototypePatternDemo, our demo class uses the ShapeCache class to get the Shape object.
Step 1
Create an abstract class that implements the Cloneable interface.
public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; }}Copy the code
Step 2
Create an entity class that extends the abstract class above.
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); }}Copy the code
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); }}Copy the code
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); }}Copy the code
Step 3
Create a class that retrieves entity classes from the database and stores them in a Hashtable.
import java.util.Hashtable; public class ShapeCache { private static Hashtable shapeMap = new Hashtable(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } // run a database query for each shape and create that shape // shapemap.put (shapeKey, shape); Public static void loadCache() {Circle = new Circle(); public static void loadCache() {Circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(),rectangle); }}Copy the code
Step 4
The PrototypePatternDemo uses the ShapeCache class to get a clone of the shape stored in the Hashtable.
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); }}Copy the code
Step 5
Execute the program and output the result:
Shape : Circle
Shape : Square
Shape : Rectangle
Copy the code