Prototype Design Pattern
Last Updated :
05 Feb, 2024
The Prototype Design Pattern is a creational pattern that enables the creation of new objects by copying an existing object. Prototype allows us to hide the complexity of making new instances from the client. The concept is to copy an existing object rather than create a new instance from scratch, something that may include costly operations. The existing object acts as a prototype and contains the state of the object.
- The newly copied object may change the same properties only if required. This approach saves costly resources and time, especially when object creation is a heavy process.
- The prototype pattern is a creational design pattern. Prototype patterns are required when object creation is a time-consuming, and costly operation, so we create objects with the existing object itself.
- One of the best available ways to create an object from existing objects is the clone() method. Clone is the simplest approach to implementing a prototype pattern. However, it is your call to decide how to copy existing objects based on your business model.
Suppose a user creates a document with a specific layout, fonts, and styling, and wishes to create similar documents with slight modifications.
Instead of starting from scratch each time, the user can use the Prototype pattern. The original document becomes the prototype, and new documents are created by cloning this prototype. This approach ensures that the new documents inherit the structure and styling of the original document while allowing for customization.
Important Topics for the Prototype Design Pattern
Components of Prototype Design Pattern
The Prototype Design Pattern’s components include the prototype interface or abstract class, concrete prototypes and the client code, and the clone
method specifying cloning behavior. These components work together to enable the creation of new objects by copying existing ones.
1. Prototype Interface or Abstract Class
The Prototype Interface or Abstract Class declares the method(s) for cloning an object. It defines the common interface that concrete prototypes must implement, ensuring that all prototypes can be cloned in a consistent manner.
- The main role is to provide a blueprint for creating new objects by specifying the cloning contract.
- It declares the
clone
method, which concrete prototypes implement to produce copies of themselves.
2. Concrete Prototype
The Concrete Prototype is a class that implements the prototype interface or extends the abstract class. It’s the class representing a specific type of object that you want to clone.
- It defines the details of how the cloning process should be carried out for instances of that class.
- Implements the
clone
method declared in the prototype interface, providing the cloning logic specific to the class.
3. Client
The Client is the code or module that requests the creation of new objects by interacting with the prototype. It initiates the cloning process without being aware of the concrete classes involved.
4. Clone Method
The Clone Method is declared in the prototype interface or abstract class. It specifies how an object should be copied or cloned. Concrete prototypes implement this method to define their unique cloning behavior. It Describes how the object’s internal state should be duplicated to create a new, independent instance.
Prototype Design Pattern example in Java
Imagine you’re working on a drawing application, and you need to create and manipulate various shapes. Each shape might have different attributes like color or size. Creating a new shape class for every variation becomes cumbersome. Also, dynamically adding or removing shapes during runtime can be challenging.
Let’s understand how Prototype Design Pattern will help to solve this problem:
- The Prototype Design Pattern helps in managing variations of shapes efficiently, promoting flexibility in shape creation, and simplifying the process of adding or removing shapes at runtime.
- The Prototype Design Pattern addresses this by introducing a prototype interface (
Shape
) that declares common methods for cloning and drawing shapes.
- Concrete prototypes like
Circle
implement this interface, providing their unique cloning logic.
- The
ShapeClient
acts as a user, utilizing the prototype to create new shapes.
1. Prototype Interface (Shape
):
We define an interface called Shape
that acts as the prototype.It declares two methods: clone()
for making a copy of itself and draw()
for drawing the shape.
Java
public interface Shape {
Shape clone();
void draw();
}
|
2. Concrete Prototype (Circle
):
We implement the Shape
interface with a concrete class Circle
. The Circle
class has a private field color
and a constructor to set the color when creating a circle. It implements the clone()
method to create a copy of itself (a new Circle
with the same color).The draw()
method is implemented to print a message indicating how the circle is drawn.
Java
public class Circle implements Shape {
private String color;
public Circle(String color) {
this .color = color;
}
@Override
public Shape clone() {
return new Circle( this .color);
}
@Override
public void draw() {
System.out.println( "Drawing a " + color + " circle." );
}
}
|
3. Client (ShapeClient
):
We create a client class, ShapeClient
, which will use the prototype to create new shapes. The client has a field shapePrototype
representing the prototype it will use. The constructor takes a Shape
prototype, and there’s a method createShape()
that creates a new shape using the prototype’s clone()
method.
Java
public class ShapeClient {
private Shape shapePrototype;
public ShapeClient(Shape shapePrototype) {
this .shapePrototype = shapePrototype;
}
public Shape createShape() {
return shapePrototype.clone();
}
}
|
4. Complete code for the above example:
In the main class, PrototypeExample
, we create a concrete prototype (circlePrototype
) of a red circle. We then create a ShapeClient
and provide it with the red circle prototype. The client uses the prototype to create a new shape (redCircle
) using the createShape()
method. Finally, we draw the newly created red circle using its draw()
method.
Java
interface Shape {
Shape clone();
void draw();
}
class Circle implements Shape {
private String color;
public Circle(String color) {
this .color = color;
}
@Override
public Shape clone() {
return new Circle( this .color);
}
@Override
public void draw() {
System.out.println( "Drawing a " + color + " circle." );
}
}
class ShapeClient {
private Shape shapePrototype;
public ShapeClient(Shape shapePrototype) {
this .shapePrototype = shapePrototype;
}
public Shape createShape() {
return shapePrototype.clone();
}
}
public class PrototypeExample {
public static void main(String[] args) {
Shape circlePrototype = new Circle( "red" );
ShapeClient client = new ShapeClient(circlePrototype);
Shape redCircle = client.createShape();
redCircle.draw();
}
}
|
When to use the Prototype Design PatternÂ
- Creating Objects is Costly:
- Use the Prototype pattern when creating objects is more expensive or complex than copying existing ones.
- If object creation involves significant resources, such as database or network calls, and you have a similar object available, cloning can be more efficient.
- Variations of Objects:
- Use the Prototype pattern when your system needs to support a variety of objects with slight variations.
- Instead of creating multiple classes for each variation, you can create prototypes and clone them with modifications.
- Dynamic Configuration:
- Use the Prototype pattern when your system requires dynamic configuration and you want to create objects with configurations at runtime.
- You can prototype a base configuration and clone it, adjusting the properties as needed.
- Reducing Initialization Overhead:
- Use the Prototype pattern when you want to reduce the overhead of initializing an object.
- Creating a clone can be faster than creating an object from scratch, especially when the initialization process is resource-intensive.
When not to use the Prototype Design PatternÂ
- Unique Object Instances:
- Avoid using the Prototype pattern when your application predominantly deals with unique object instances, and the overhead of implementing the pattern outweighs its benefits.
- Simple Object Creation:
- If object creation is simple and does not involve significant resource consumption, and there are no variations of objects, using the Prototype pattern might be unnecessary complexity.
- Immutable Objects:
- If your objects are immutable (unchangeable) and do not need variations, the benefits of cloning may not be significant.
- Immutable objects are often safely shared without the need for cloning.
- Clear Object Creation Process:
- If your system has a clear and straightforward object creation process that is easy to understand and manage, introducing the Prototype pattern may add unnecessary complexity.
- Limited Object Variations:
- If there are only a few variations of objects, and creating subclasses or instances with specific configurations is manageable, the Prototype pattern might be overkill.
Â
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...