📁 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:
Post a Comment