Saturday, February 15, 2025

C++ Creational Factory

📁 File Structure

/ProjectFolder
│── Product.h
│── ConcreteProduct.h
│── ConcreteProduct.cpp
│── Creator.h
│── ConcreteCreator.h
│── ConcreteCreator.cpp
│── main.cpp
    

1. Product.h (Abstract Product)

#ifndef PRODUCT_H
#define PRODUCT_H

#include <iostream>

// Abstract Product class
class Product {
public:
    virtual void use() = 0; // Pure virtual function to be implemented by concrete products
    virtual ~Product() {} // Virtual destructor for proper cleanup
};

#endif // PRODUCT_H
    

2. ConcreteProduct.h & ConcreteProduct.cpp (Concrete Implementations)

ConcreteProduct.h

#ifndef CONCRETEPRODUCT_H
#define CONCRETEPRODUCT_H

#include "Product.h"

// Concrete Product class
class ConcreteProductA : public Product {
public:
    void use() override; // Implementation of abstract method
};

class ConcreteProductB : public Product {
public:
    void use() override;
};

#endif // CONCRETEPRODUCT_H
    

ConcreteProduct.cpp

#include "ConcreteProduct.h"

// Implement ConcreteProductA's behavior
void ConcreteProductA::use() {
    std::cout << "Using ConcreteProductA" << std::endl;
}

// Implement ConcreteProductB's behavior
void ConcreteProductB::use() {
    std::cout << "Using ConcreteProductB" << std::endl;
}
    

3. Creator.h (Abstract Factory Class)

#ifndef CREATOR_H
#define CREATOR_H

#include "Product.h"

// Abstract Factory class
class Creator {
public:
    virtual Product* factoryMethod() = 0; // Factory method to create objects
    virtual ~Creator() {} // Virtual destructor
};

#endif // CREATOR_H
    

4. ConcreteCreator.h & ConcreteCreator.cpp (Factory Implementations)

ConcreteCreator.h

#ifndef CONCRETECREATOR_H
#define CONCRETECREATOR_H

#include "Creator.h"
#include "ConcreteProduct.h"

// Concrete Creator for ProductA
class ConcreteCreatorA : public Creator {
public:
    Product* factoryMethod() override;
};

// Concrete Creator for ProductB
class ConcreteCreatorB : public Creator {
public:
    Product* factoryMethod() override;
};

#endif // CONCRETECREATOR_H
    

ConcreteCreator.cpp

#include "ConcreteCreator.h"

// Factory method returns an instance of ConcreteProductA
Product* ConcreteCreatorA::factoryMethod() {
    return new ConcreteProductA();
}

// Factory method returns an instance of ConcreteProductB
Product* ConcreteCreatorB::factoryMethod() {
    return new ConcreteProductB();
}
    

5. main.cpp (Client Code)

#include <iostream>
#include "ConcreteCreator.h"

int main() {
    // Create a factory for ProductA
    Creator* creatorA = new ConcreteCreatorA();
    Product* productA = creatorA->factoryMethod();
    productA->use(); // Output: Using ConcreteProductA

    // Create a factory for ProductB
    Creator* creatorB = new ConcreteCreatorB();
    Product* productB = creatorB->factoryMethod();
    productB->use(); // Output: Using ConcreteProductB

    // Cleanup
    delete productA;
    delete creatorA;
    delete productB;
    delete creatorB;

    return 0;
}
    

🎯 Key Takeaways

  • Encapsulation: The factory method ensures the client only depends on the abstract Product interface, not concrete classes.
  • Scalability: Adding new products only requires adding new concrete products and their corresponding creators.
  • Decoupling: The client does not depend on the actual product classes.

No comments:

Abstract Factory Pattern in C#

Below is a C# implementation of the Abstract Factory design pattern, a Creational pattern, following the Gang of Four (GoF) structure....