Design Patterns | Set 2 (Factory Method) - GeeksforGeeks

07 Oct, 2021
Factory method is a creational design pattern, i.e., related to object creation. In Factory pattern, we create objects without exposing the creation logic to the client and the client uses the same common interface to create a new type of object. 
The idea is to use a static member-function (static factory method) that creates & returns instances, hiding the details of class modules from the 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.
What is meant when we talk about libraries and clients? A library is something that is provided by some third party that exposes some public APIs and clients make calls to those public APIs to complete their tasks. A very simple example can be different kinds of Views provided by Android OS.  Why factory pattern? Let us understand it with an example:  
C
// A design without factory pattern#include <iostream>using namespace std; // Library classesclass 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) classclass 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 programint main() {    Client *pClient = new Client(1);    Vehicle * pVehicle = pClient->getVehicle();    pVehicle->printVehicle();    return 0;}
Output: 
I am two wheeler
What are the problems with the above design? As you must have observed in the above example, the Client creates objects of either TwoWheeler or FourWheeler based on some input during constructing its object. Say, the library introduces a new class ThreeWheeler to incorporate three-wheeler vehicles also. What would happen? The client will end up chaining a new else if in the conditional ladder to create objects of ThreeWheeler. Which in turn will need the Client to be recompiled. So, each time a new change is made at the library side, the Client would need to make some corresponding changes at its end and recompile the code. Sounds bad? This is a very bad practice of design.
How to avoid the problem? The answer is, create a static (or factory) method. Let us see the below code. 
C
// C++ program to demonstrate factory method design pattern#include <iostream>using namespace std; enum VehicleType {    VT_TwoWheeler,    VT_ThreeWheeler,    VT_FourWheeler}; // Library classesclass 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 typeVehicle* 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 classclass 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 programint main() {    Client *pClient = new Client();    Vehicle * pVehicle = pClient->getVehicle();    pVehicle->printVehicle();    return 0;}
Output: 
I am three wheeler
In the above example, we have totally decoupled the selection of types for object creation from the Client. The library is now responsible to decide which object type to create based on an input. Client just needs to make calls to the library’s factory Create method and pass the type it wants without worrying about the actual implementation of the creation of objects.
Other examples of Factory Method: 
Say, in a ‘Drawing’ system, depending on the user’s input, different pictures like square, rectangle, the circle can be drawn. Here we can use the factory method to create instances depending on the user’s input. For adding a new type of shape, no need to change the client’s code.Another example: On the travel site, we can book train tickets as well bus tickets and flight tickets. In this case, the user can give his travel type as ‘bus’, ‘train’, or ‘flight’. Here we have an abstract class ‘AnyTravel’ with a static member function ‘GetObject’ which depending on the user’s travel type, will create & return an object of ‘BusTravel’ or ‘ TrainTravel’. ‘BusTravel’ or ‘ TrainTravel’ have common functions like passenger name, Origin, destination parameters.
Say, in a ‘Drawing’ system, depending on the user’s input, different pictures like square, rectangle, the circle can be drawn. Here we can use the factory method to create instances depending on the user’s input. For adding a new type of shape, no need to change the client’s code.
Another example: On the travel site, we can book train tickets as well bus tickets and flight tickets. In this case, the user can give his travel type as ‘bus’, ‘train’, or ‘flight’. Here we have an abstract class ‘AnyTravel’ with a static member function ‘GetObject’ which depending on the user’s travel type, will create & return an object of ‘BusTravel’ or ‘ TrainTravel’. ‘BusTravel’ or ‘ TrainTravel’ have common functions like passenger name, Origin, destination parameters.
Further Read: Factory Method in PythonPlease write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Pushpender007
dsudhakar07
Design Pattern
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
SDE SHEET - A Complete Guide for SDE Preparation
Factory method design pattern in Java
Unified Modeling Language (UML) | An Introduction
MVC Design Pattern
Builder Design Pattern
Composite Design Pattern
Unified Modeling Language (UML) | State Diagrams
Unified Modeling Language (UML) | Activity Diagrams
Abstract Factory Pattern
How to design a parking lot using object-oriented principles?