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; }