C++ Factory Method Pattern Example

1. Definition

The Factory Method Design Pattern is a creational pattern that provides an interface for creating objects in a super class, but allows subclasses to alter the type of objects that will be created. Rather than calling a class constructor directly, a method is used to create the object, acting as a "factory" for that object.

2. Problem Statement

Consider a scenario where a software library offers a UI toolkit, but it doesn't know what specific operating system it will be running on. If we directly instantiate UI elements suited for one OS, it may not be compatible with others. Thus, there's a need to create OS-specific UI elements without knowing the exact OS in advance.

3. Solution

The Factory Method Pattern addresses this by defining a method that will be used for object creation and lets the subclasses decide which class to instantiate. This allows the base class to delegate the responsibility of object instantiation to the derived classes.

4. Real-World Use Cases

1. GUI libraries where each OS provides a different implementation of a button or a window.

2. Database connection drivers where the connection method might differ based on the database type.

5. Implementation Steps

1. Create an abstract base class (or interface) with a factory method declaration.

2. Concrete classes will implement this factory method to instantiate and return the required object.

3. The client will use the factory method of the concrete class to get the object.

6. Implementation in C++

#include<iostream>
// Abstract base class (Product)
class Button {
public:
    virtual void render() = 0;
};
// Concrete product class 1
class WindowsButton : public Button {
public:
    void render() {
        std::cout << "Rendering a Windows button." << std::endl;
    }
};
// Concrete product class 2
class MacOSButton : public Button {
public:
    void render() {
        std::cout << "Rendering a MacOS button." << std::endl;
    }
};
// Abstract Creator class
class GUIFactory {
public:
    virtual Button* createButton() = 0;
};
// Concrete creator class 1
class WindowsFactory : public GUIFactory {
public:
    Button* createButton() {
        return new WindowsButton();
    }
};
// Concrete creator class 2
class MacOSFactory : public GUIFactory {
public:
    Button* createButton() {
        return new MacOSButton();
    }
};
int main() {
    GUIFactory* factory = new WindowsFactory();
    Button* btn = factory->createButton();
    btn->render();
    delete btn;
    delete factory;
    return 0;
}

Output:

Rendering a Windows button.

Explanation:

1. Button is the abstract product class with a virtual method render.

2. WindowsButton and MacOSButton are concrete products that provide implementations for the render method.

3. GUIFactory is the abstract creator class with a virtual factory method createButton.

4. WindowsFactory and MacOSFactory are concrete creators that implement the factory method to return a concrete product.

5. In the main function, a Windows button is created and rendered as an example.

7. When to use?

Use the Factory Method pattern when:

1. The exact type of the object isn't known until runtime.

2. The creation process is complex or involves multiple steps.

3. The product needs to be extensible, and the library wants to provide a way for clients to extend available products easily.


Comments