Concrete Factory
… is a class that creates objects without exposing the instantiation logic.
#include <memory>
class Car {};
class VWCar : public Car {};
class BMWCar : public Car {};
class CarFactory {
public:
enum CarType { VW, BMW };
std::unique_ptr<Car> createCar(CarType type) {
switch(type) {
case VW: return std::make_unique<VWCar>(); break;
case BMW: return std::make_unique<BMWCar>(); break;
}
}
};
int main() {
CarFactory carFactory;
std::unique_ptr<Car> vwCar = carFactory.createCar(CarFactory::VW);
std::unique_ptr<Car> bmwCar = carFactory.createCar(CarFactory::BMW);
// ...
return 0;
}
Abstract Factory
… is a class which delegates the object creation to its subclasses (concrete factories).
#include <memory>
class Car {};
class VWCar : public Car {};
class BMWCar : public Car {};
class CarFactory {
public:
virtual std::unique_ptr<Car> createCar() = 0;
};
class VWFactory : public CarFactory {
public:
std::unique_ptr<Car> createCar() { return std::make_unique<VWCar>(); }
};
class BMWFactory : public CarFactory {
public:
std::unique_ptr<Car> createCar() { return std::make_unique<BMWCar>(); }
};
int main() {
VWFactory vwFactory;
BMWFactory bmwFactory;
std::unique_ptr<Car> vwCar = vwFactory.createCar();
std::unique_ptr<Car> bmwCar = bmwFactory.createCar();
// ...
return 0;
}
Factory Method
… is a method within a class for an object creation and it gets implemented (if pure virtual) or possibly overritten (if virtual) in the subclasses.
#include <memory>
class Car {};
class VWCar : public Car {};
class BMWCar : public Car {};
class Engineer {
public:
void buildCar() {
std::unique_ptr<Car> car = createCar();
}
protected:
virtual std::unique_ptr<Car> createCar() = 0;
};
class VWEngineer: public Engineer {
protected:
std::unique_ptr<Car> createCar() override { return std::make_unique<VWCar>(); }
};
class BMWEngineer: public Engineer {
protected:
std::unique_ptr<Car> createCar() override { return std::make_unique<BMWCar>(); }
};
int main() {
VWEngineer vwEngineer;
BMWEngineer bmwEngineer;
vwEngineer.buildCar();
bmwEngineer.buildCar();
// ...
return 0;
}