Factory (Design Pattern)

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