What is Prototype design pattern and it’s advantage of using Prototype design Pattern in java
What is Prototype design pattern?
The Prototype Pattern is a creational design pattern that is used when creating an instance of a class is more expensive than copying an existing instance. Instead of creating a new instance of a class, the prototype pattern involves creating new objects by copying an existing object, known as the prototype. This pattern allows for the creation of new objects with the same state as an existing object, providing a way to create new instances efficiently.
Here’s a simple example of the Prototype Pattern in Java:
Example# 1:
/*
* Author: Zameer Ali Mohil
* */
// Prototype interface
interface Prototype {
Prototype clone();
void displayInfo();
}
// ConcretePrototype class
class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
@Override
public Prototype clone() {
return new ConcretePrototype(this.name);
}
@Override
public void displayInfo() {
System.out.println("ConcretePrototype: " + name);
}
}
// Client code
public class PrototypePatternExample {
public static void main(String[] args) {
// Create an instance of ConcretePrototype
Prototype original = new ConcretePrototype("Original Object");
original.displayInfo();
// Clone the original object to create a new instance
Prototype clone = original.clone();
clone.displayInfo();
}
}
In this example:
- The
Prototype
interface declares aclone
method for creating a copy of an object and adisplayInfo
method for displaying information. - The
ConcretePrototype
class implements thePrototype
interface. It has aname
attribute and provides a concrete implementation of theclone
method. - The
PrototypePatternExample
class demonstrates the use of the prototype pattern by creating an original object and then cloning it to create a new instance.
When you run the PrototypePatternExample
class, you’ll see output indicating that the clone has the same state as the original object:
ConcretePrototype: Original Object
ConcretePrototype: Original Object
The Prototype Pattern is particularly useful when creating new objects involves complex initialization or when the construction of a new instance is more resource-intensive. Instead of creating a new object from scratch, the prototype pattern allows you to clone an existing object and then customize it if needed.
Example# 2:
Let’s consider a more complex example involving a hierarchy of bird species. We’ll use the prototype pattern with inheritance to create and clone instances of different bird species.
// Bird interface with clone method
public interface Bird extends Cloneable {
void fly();
Bird clone();
}
// Base class for bird species
public abstract class BirdSpecies implements Bird {
private String speciesName;
public BirdSpecies(String speciesName) {
this.speciesName = speciesName;
}
public String getSpeciesName() {
return speciesName;
}
@Override
public abstract void fly();
@Override
public Bird clone() {
try {
return (Bird) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
// Concrete implementation for a specific bird species: Sparrow
public class Sparrow extends BirdSpecies {
public Sparrow() {
super("Sparrow");
}
@Override
public void fly() {
System.out.println(getSpeciesName() + " is flying around.");
}
}
// Concrete implementation for another bird species: Penguin
public class Penguin extends BirdSpecies {
public Penguin() {
super("Penguin");
}
@Override
public void fly() {
System.out.println(getSpeciesName() + " cannot fly.");
}
}
// Client code
public class BirdClient {
public static void main(String[] args) {
// Create instances of different bird species
Bird sparrow = new Sparrow();
Bird penguin = new Penguin();
// Clone instances
Bird clonedSparrow = sparrow.clone();
Bird clonedPenguin = penguin.clone();
// Test the fly method on original and cloned instances
sparrow.fly(); // Sparrow is flying around.
clonedSparrow.fly(); // Sparrow is flying around.
penguin.fly(); // Penguin cannot fly.
clonedPenguin.fly(); // Penguin cannot fly.
}
}
In this example, we have a base class BirdSpecies
that implements the Bird
interface and provides a common implementation for the clone
method. Concrete bird species, such as Sparrow
and Penguin
, extend this base class and implement the fly
method.
The client code demonstrates creating instances of different bird species, cloning them, and then calling the fly
method on both the original and cloned instances. The prototype pattern, combined with inheritance, allows for the creation and customization of different bird species.
Advantage of using Prototype design Pattern
The Prototype Design Pattern offers several advantages in certain scenarios:
1. Efficient Object Creation: The primary advantage of the Prototype Pattern is that it allows for efficient object creation. Instead of creating new objects by invoking their constructors, which may involve complex initialization processes, objects can be cloned from existing instances.
2. Reduced Cost of Object Creation: Cloning an existing object is often less resource-intensive than creating a new object from scratch. This can be especially beneficial in situations where creating an object involves costly operations such as database queries, network calls, or heavy computations.
3. Flexibility in Object Creation: The Prototype Pattern provides flexibility in object creation by allowing clients to create new objects by copying existing ones. Clients can customize the cloned objects as needed, providing a convenient way to create variations of existing objects.
4. Simplifies Object Initialization: The pattern simplifies object initialization by using an existing object as a template. Clients only need to modify the cloned object if they want to change specific attributes, avoiding the need to understand or duplicate complex initialization logic.
5. Enhances Design Independence: By decoupling the client code from the concrete classes of objects, the Prototype Pattern promotes design independence. Clients can work with a common interface (e.g., the Prototype interface) and don’t need to be aware of the specific classes being instantiated.
6. Supports Dynamic Configuration: The Prototype Pattern supports dynamic configuration of objects. Clients can create prototypes with default configurations and then modify specific attributes or settings based on dynamic requirements. This is especially useful in scenarios where configuration changes at runtime.
7. Avoids Subclass Proliferation: In situations where there are multiple variations of objects, the Prototype Pattern can help avoid subclass proliferation. Instead of creating numerous subclasses for each variation, clients can clone a prototype and make necessary modifications.
8. Encourages Design Reuse: Design reuse is promoted through the use of prototypes. Existing objects, with their configurations and behaviors, can serve as templates for creating new objects. This reuse contributes to a more modular and maintainable design.
It’s important to note that while the Prototype Pattern has its advantages, it may not be suitable for all scenarios. It is most effective when the cost of creating a new object is relatively high compared to cloning, and when objects can be configured or customized easily after creation.