prototype design pattern

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:

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 a clone method for creating a copy of an object and a displayInfo method for displaying information.
  • The ConcretePrototype class implements the Prototype interface. It has a name attribute and provides a concrete implementation of the clone 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:

Output

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.

prototype design pattern

Example 2
// 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.

Leave a Reply

Your email address will not be published. Required fields are marked *