Factory Pattern in C++


Reading time: 20 minutes

Factory method also known as a static class is a creational design pattern, i.e. it is related to object creation.

In this we create object without exposing the creation logic to client and the client use the same common interface to create new type of object.
The idea is to use a static member-function (static factory method) which creates & returns instances, hiding the details of class modules from user.

A factory pattern is one of the core design principles to create an object, allowing clients to create objects of a library(explained below) in a way such that it doesn’t have tight coupling with the class hierarchy of the library.

Note : It is a virtual constructor hence not available in C++

Factory Method pattern is generally used in the following situations:

  1. A class cannot anticipate the type of objects it needs to create beforehand.
  2. A class requires its subclasses to specify the objects it creates.
  3. You want to localize the logic to instantiate a complex object.

Why do we need factory pattern?

We will demonstrate this with a code example not using factory pattern and pointing out the problems with it.

A design without factory pattern

#include <iostream> 
using namespace std; 
  
// Library classes 
class Vehicle { 
public: 
    virtual void printVehicle() = 0; 
}; 
class TwoWheeler : public Vehicle { 
public: 
    void printVehicle()  { 
        cout << "I am two wheeler" << endl; 
    } 
}; 
class FourWheeler : public Vehicle { 
    public: 
    void printVehicle()  { 
        cout << "I am four wheeler" << endl; 
    } 
}; 
  
// Client (or user) class 
class Client { 
public: 
    Client(int type)  { 
  
        // Client explicitly creates classes according to type 
        if (type == 1) 
            pVehicle = new TwoWheeler(); 
        else if (type == 2) 
            pVehicle = new FourWheeler(); 
        else
            pVehicle = NULL; 
    } 
  
    ~Client()   { 
        if (pVehicle) 
        { 
            delete[] pVehicle; 
            pVehicle = NULL; 
        } 
    } 
  
    Vehicle* getVehicle() { 
        return pVehicle; 
    } 
private: 
    Vehicle *pVehicle; 
}; 
  
// Driver program 
int main() { 
    Client *pClient = new Client(1); 
    Vehicle * pVehicle = pClient->getVehicle(); 
    pVehicle->printVehicle(); 
    return 0; 
} 

Output :

I am two wheeler
topic of image

Problem with above code

As you must have observed in the above example, Client creates objects of either TwoWheeler or FourWheeler based on some input during constructing its object.
Say, library introduces a new class ThreeWheeler to incorporate three wheeler vehicles also. What would happen? Client will end up chaining a new else if in the conditional ladder to create objects of ThreeWheeler. Which in turn will need Client to be recompiled. So, each time a new change is made at the library side, Client would need to make some corresponding changes at its end and recompile the code. Sounds bad? This is considered to be a very bad practice of design.

C++ program to demonstrate factory method design pattern

#include <iostream> 
using namespace std; 
  
enum VehicleType { 
    VT_TwoWheeler,    VT_ThreeWheeler,    VT_FourWheeler 
}; 
  
// Library classes 
class Vehicle { 
public: 
    virtual void printVehicle() = 0; 
    static Vehicle* Create(VehicleType type); 
}; 
class TwoWheeler : public Vehicle { 
public: 
    void printVehicle() { 
        cout << "I am two wheeler" << endl; 
    } 
}; 
class ThreeWheeler : public Vehicle { 
public: 
    void printVehicle() { 
        cout << "I am three wheeler" << endl; 
    } 
}; 
class FourWheeler : public Vehicle { 
    public: 
    void printVehicle() { 
        cout << "I am four wheeler" << endl; 
    } 
}; 
  
// Factory method to create objects of different types. 
// Change is required only in this function to create a new object type 
Vehicle* Vehicle::Create(VehicleType type) { 
    if (type == VT_TwoWheeler) 
        return new TwoWheeler(); 
    else if (type == VT_ThreeWheeler) 
        return new ThreeWheeler(); 
    else if (type == VT_FourWheeler) 
        return new FourWheeler(); 
    else return NULL; 
} 
  
// Client class 
class Client { 
public: 
  
    // Client doesn't explicitly create objects 
    // but passes type to factory method "Create()" 
    Client() 
    { 
        VehicleType type = VT_ThreeWheeler; 
        pVehicle = Vehicle::Create(type); 
    } 
    ~Client() { 
        if (pVehicle) { 
            delete[] pVehicle; 
            pVehicle = NULL; 
        } 
    } 
    Vehicle* getVehicle()  { 
        return pVehicle; 
    } 
  
private: 
    Vehicle *pVehicle; 
}; 
  
// Driver program 
int main() { 
    Client *pClient = new Client(); 
    Vehicle * pVehicle = pClient->getVehicle(); 
    pVehicle->printVehicle(); 
    return 0; 
} 

Output :

I am three wheeler
topic of image

In the above example, we have totally decoupled the selection of type for object creation from Client. The library is now responsible to decide which object type to create based on an input. Client just needs to make call to library’s factory Create method and pass the type it wants without worrying about the actual implementation of creation of objects.

Difference between factory method and abstract factory method

The Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.

 // Factory Method   
    class A {
    public void doSomething() {
        Foo f = makeFoo();
        f.whatever();   
    }

    protected Foo makeFoo() {
        return new RegularFoo();
    }
}

class B extends A {
    protected Foo makeFoo() {
        //subclass is overriding the factory method 
        //to return something different
        return new SpecialFoo();
    }
}

The Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition.

 //Abstract factory   
 class A {
    private Factory factory;

    public A(Factory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        //The concrete class of "f" depends on the concrete class
        //of the factory passed into the constructor. If you provide a
        //different factory, you get a different Foo object.
        Foo f = factory.makeFoo();
        f.whatever();
    }
}

interface Factory {
    Foo makeFoo();
    Bar makeBar();
    Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}