C++ Prototype Design Pattern Example

1. Definition

The Prototype Design Pattern is a creational pattern that creates objects by cloning an existing object, known as the prototype, rather than constructing a new instance from scratch.

2. Problem Statement

Consider a situation where instantiating a new object is more costly in terms of resources or time, e.g., when objects require considerable time to be created, configured, and populated. In such cases, creating new instances from scratch each time is inefficient.

3. Solution

The Prototype pattern provides a mechanism to copy an existing object, thus bypassing the overhead of creating and initializing the object from scratch. This can be done by having a clone method in the prototype object, which creates and returns a copy of itself.

4. Real-World Use Cases

1. Copying configurations or settings from a master object to avoid redundant setups.

2. Spawning game objects that are clones of a prototype.

3. Creating objects in an undo/redo system where states are saved as object clones.

5. Implementation Steps

1. Create an abstract base class (or interface) with a pure virtual clone method.

2. Derive concrete classes from this base class.

3. Implement the clone method in the concrete classes to return a copy of the object.

4. Use the clone method to create new objects instead of the constructor.

6. Implementation in C++

// Abstract prototype base class
class Prototype {
public:
    virtual ~Prototype() {}
    virtual Prototype* clone() const = 0;
};
// Concrete prototype class
class ConcretePrototype : public Prototype {
    int data;
public:
    ConcretePrototype(int d) : data(d) {}
    ConcretePrototype(const ConcretePrototype& cp) : data(cp.data) {}
    Prototype* clone() const override {
        return new ConcretePrototype(*this);  // Calls the copy constructor
    }
    void display() const {
        std::cout << "Data: " << data << std::endl;
    }
};
int main() {
    // Create a prototype instance
    ConcretePrototype prototype(42);
    // Clone the prototype
    Prototype* cloned = prototype.clone();
    // Cast back to ConcretePrototype to use display method
    static_cast<ConcretePrototype*>(cloned)->display();
    delete cloned;
    return 0;
}

Output:

Data: 42

Explanation:

1. Prototype is the abstract base class that defines the clone method.

2. ConcretePrototype is a concrete class that implements the clone method by calling its copy constructor.

3. In the main function, an instance of ConcretePrototype is created.

4. Using the clone method, a new object is created that's a copy of the original prototype.

5. The display method is called to show that the cloned object contains the same data as the original.

7. When to use?

Use the Prototype pattern when:

1. Objects have numerous shared configurations and only a few differences, and creating a new instance is more expensive than copying an existing one.

2. Classes to instantiate are specified at runtime, and you want to avoid building a class hierarchy of factories paralleling the class hierarchy of products.

3. Instances of a class can have one of a few different combinations of state, and it's more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually each time.


Comments