Factory Method Pattern

The Factory Method design pattern is a creational pattern that provides an interface for creating objects but allows subclasses to decide which class to instantiate. It is useful when you have a super class with multiple sub-classes, and the exact class to be instantiated is determined at runtime based on certain conditions or requirements.

Factory Method Pattern C++:

Let’s consider a simple example of a Shape hierarchy with different shapes (Circle, Square) as subclasses. We’ll use the Factory Method pattern to create instances of these shapes based on the user’s choice.

#include <iostream>
#include <memory>

// Abstract base class for shapes
class Shape {
public:
    virtual void draw() = 0;
};

// Concrete class for Circle
class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a Circle." << std::endl;
    }
};

// Concrete class for Square
class Square : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a Square." << std::endl;
    }
};

// Abstract Factory class
class ShapeFactory {
public:
    virtual std::shared_ptr<Shape> createShape() = 0;
};

// Concrete Factory class for Circle
class CircleFactory : public ShapeFactory {
public:
    std::shared_ptr<Shape> createShape() override {
        return std::make_shared<Circle>();
    }
};

// Concrete Factory class for Square
class SquareFactory : public ShapeFactory {
public:
    std::shared_ptr<Shape> createShape() override {
        return std::make_shared<Square>();
    }
};

int main() {
    // Create Circle using CircleFactory
    ShapeFactory* circleFactory = new CircleFactory();
    std::shared_ptr<Shape> circle = circleFactory->createShape();
    circle->draw(); // Output: Drawing a Circle.

    // Create Square using SquareFactory
    ShapeFactory* squareFactory = new SquareFactory();
    std::shared_ptr<Shape> square = squareFactory->createShape();
    square->draw(); // Output: Drawing a Square.

    // Clean up
    delete circleFactory;
    delete squareFactory;

    return 0;
}

Explanation:
In the code above, we have a Shape hierarchy with two concrete classes, Circle and Square, each implementing the draw() method. These classes represent different shapes that can be drawn.

Next, we define an abstract ShapeFactory class with a pure virtual function createShape(), which acts as the factory method. The factory method is responsible for creating instances of the shapes based on the concrete factory class.

We have two concrete factory classes, CircleFactory and SquareFactory, each inheriting from the ShapeFactory class. These concrete factory classes override the createShape() method and return the corresponding shape object (Circle or Square) using the std::make_shared function.

In the main() function, we demonstrate how the Factory Method pattern works. We create instances of shapes using the factory methods. By using the factory methods, the client code does not need to know the specific classes of the shapes it creates, promoting loose coupling between the client code and the shape classes.

Advantages of Factory Method Pattern:

  1. Decouples client code from the concrete classes, promoting flexibility and scalability.
  2. Simplifies the addition of new classes (shapes in this case) to the hierarchy without modifying the existing client code.
  3. Centralizes object creation in factory classes, making it easier to manage object creation logic.

Disadvantages of Factory Method Pattern:

  1. The code can become more complex due to the introduction of multiple classes (factories) for creating objects.
  2. Requires additional maintenance when adding new subclasses and their corresponding factory classes.

In summary, the Factory Method pattern is a useful design pattern when you want to create objects of a family of related classes without specifying their concrete classes in the client code. It provides a clean and extensible way to create objects based on runtime requirements.

Leave a Reply