Factory method Design Pattern

Last Updated : 14 Sep, 2026

The Factory Method is a creational design pattern that defines an interface for creating objects but lets subclasses decide which object to instantiate. It promotes loose coupling by delegating object creation to a method, making the system more flexible and extensible.

  • Subclasses override the factory method to create specific object types, enabling flexible object creation.
  • Supports easy addition of new product types and improves maintainability and adaptability at runtime.

Example: Consider a notification system that can send Email, SMS, or Push notifications. Instead of directly creating EmailNotification, SMSNotification, or PushNotification objects, the application uses a factory method to create the required notification.

notificationfactory
Factory Method Design Pattern

In the Diagram:

  • If the user selects Email, an EmailNotification object is created.
  • If the user selects SMS, an SMSNotification object is created.
  • If the user selects Push, a PushNotification object is created.

Note: The main code only calls the factory method and doesn’t worry about which object is created.

Real World Applications

The Factory Method Pattern is widely used in software development to create objects dynamically while keeping the client code independent of their concrete classes.

  • Payment systems: A payment system can create different payment processors such as card, UPI, or wallet processors.
  • Game development: A game can create different enemies, weapons, or items depending on the game level or environment.
  • Document processing: An application can create different document objects such as PDF, Word, or text documents.
  • Notification systems: An application can create Email, SMS, or Push notification objects based on the required notification type.

Components

The main components of Factory Design Pattern:

  • Creator: This is an abstract class or an interface that declares the factory method. The creator typically contains a method that serves as a factory for creating objects. It may also contain other methods that work with the created objects.
  • Concrete Creator: Concrete Creator classes are subclasses of the Creator that implement the factory method to create specific types of objects. Each Concrete Creator is responsible for creating a particular product.
  • Product: This is the interface or abstract class for the objects that the factory method creates. The Product defines the common interface for all objects that the factory method can create.
  • Concrete Product: Concrete Product classes are the actual objects that the factory method creates. Each Concrete Product class implements the Product interface or extends the Product abstract class.

Implementation Example

The problem statement to understand Factory Method Design Pattern:

Consider a software application that needs to handle the creation of various types of vehicles, such as Two Wheelers, Three Wheelers and Four Wheelers. Each type of vehicle has its own specific properties and behaviors.

1. Without Factory Method Design Pattern

C++
#include <iostream>
using namespace std;

class Vehicle
{
  public:
    // Pure virtual function
    virtual void printVehicle() = 0;
};

class TwoWheeler : public Vehicle
{
  public:
    void printVehicle() override
    {
        cout << "I am two wheeler" << endl;
    }
};

class FourWheeler : public Vehicle
{
  public:
    void printVehicle() override
    {
        cout << "I am four wheeler" << endl;
    }
};

// Client (or user) class
class Client
{
  private:
    Vehicle *pVehicle;

  public:
    Client(int type)
    {
        if (type == 1)
        {
            pVehicle = new TwoWheeler();
        }
        else if (type == 2)
        {
            pVehicle = new FourWheeler();
        }
        else
        {
            pVehicle = nullptr;
        }
    }

    void cleanup()
    {
        if (pVehicle != nullptr)
        {
            delete pVehicle;
            pVehicle = nullptr;
        }
    }

    Vehicle *getVehicle()
    {
        return pVehicle;
    }
};

// Driver Code
int main()
{
    Client pClient(1);
    Vehicle *pVehicle = pClient.getVehicle();
    if (pVehicle != nullptr)
    {
        pVehicle->printVehicle();
    }
    pClient.cleanup();
    return 0;
}
Java
import java.io.*;

// Library classes
abstract class Vehicle {
    public abstract void printVehicle();
}

class TwoWheeler extends Vehicle {
    public void printVehicle()
    {
        System.out.println("I am two wheeler");
    }
}

class FourWheeler extends Vehicle {
    public void printVehicle()
    {
        System.out.println("I am four wheeler");
    }
}

// Client (or user) class
class Client {
    private Vehicle pVehicle;

    public Client(int type)
    {
        if (type == 1) {
            pVehicle = new TwoWheeler();
        }
        else if (type == 2) {
            pVehicle = new FourWheeler();
        }
        else {
            pVehicle = null;
        }
    }

    public void cleanup()
    {
        if (pVehicle != null) {
            pVehicle = null;
        }
    }

    public Vehicle getVehicle() { return pVehicle; }
}

// Driver Code
public class GFG {
    public static void main(String[] args)
    {
        Client pClient = new Client(1);
        Vehicle pVehicle = pClient.getVehicle();
        if (pVehicle != null) {
            pVehicle.printVehicle();
        }
        pClient.cleanup();
    }
}
Python
from abc import ABC, abstractmethod

# Library classes
class Vehicle(ABC):
    @abstractmethod
    def printVehicle(self):
        pass


class TwoWheeler(Vehicle):
    def printVehicle(self):
        print("I am two wheeler")


class FourWheeler(Vehicle):
    def printVehicle(self):
        print("I am four wheeler")

# Client (or user) class


class Client:
    def __init__(self, type):
        if type == 1:
            self.pVehicle = TwoWheeler()
        elif type == 2:
            self.pVehicle = FourWheeler()
        else:
            self.pVehicle = None

    def cleanup(self):
        if self.pVehicle is not None:
            self.pVehicle = None

    def getVehicle(self):
        return self.pVehicle

# Driver Code


def main():
    pClient = Client(1)
    pVehicle = pClient.getVehicle()
    if pVehicle is not None:
        pVehicle.printVehicle()
    pClient.cleanup()


if __name__ == "__main__":
    main()
JavaScript
// Library classes
class Vehicle {
    printVehicle()
    {
        throw new Error(
            "printVehicle() must be implemented");
    }
}

class TwoWheeler extends Vehicle {
    printVehicle() { console.log("I am two wheeler"); }
}

class FourWheeler extends Vehicle {
    printVehicle() { console.log("I am four wheeler"); }
}

// Client (or user) class
class Client {
    constructor(type)
    {
        if (type === 1) {
            this.pVehicle = new TwoWheeler();
        }
        else if (type === 2) {
            this.pVehicle = new FourWheeler();
        }
        else {
            this.pVehicle = null;
        }
    }

    cleanup()
    {
        if (this.pVehicle !== null) {
            this.pVehicle = null;
        }
    }

    getVehicle() { return this.pVehicle; }
}

// Driver Code
function main()
{
    const pClient = new Client(1);
    const pVehicle = pClient.getVehicle();
    if (pVehicle !== null) {
        pVehicle.printVehicle();
    }
    pClient.cleanup();
}

main();

Output
I am two wheeler

Issues with the Current Design

Although the code works, the Client class has too much responsibility.

  • Tight coupling: The client directly depends on TwoWheeler and FourWheeler.
  • Violation of SRP(Single Responsibility Principle): Client handles both product creation and usage.
  • Hard to extend: Adding a new vehicle requires modifying the client.
  • Conditional logic grows: More vehicle types can lead to larger if-else or switch statements.

For example: If we add ThreeWheeler, the client needs another condition:

else if (type == 3) {
pVehicle = new ThreeWheeler();
}

This means every new vehicle type requires a change in the client.

Solutions to the Problems

  • Define a Factory Interface: Create an interface, VehicleFactory, with a method to produce vehicles.
  • Create Specific Factories: Implement classes like TwoWheelerFactory and FourWheelerFactory that follow the VehicleFactory interface, providing methods for each vehicle type.
  • Revise the Client Class: Change the Client class to use a VehicleFactory instance instead of creating vehicles directly. This way, it can request vehicles without using conditional logic.
  • Enhance Flexibility: This structure allows for easy addition of new vehicle types by simply creating new factory classes, without needing to alter existing Client code.

2. With Factory Method Design Pattern

The Factory Method Design Pattern separates object creation from object usage. Instead of creating objects directly, the client uses a factory to create the required object.

Client -> VehicleFactory -> TwoWheeler

Let's breakdown the code into component wise code:

factory_method_design_pattern_class_diagram
Factory Method Design Pattern

1. Product Interface

Product interface representing a vehicle

C++
#include <iostream>
#include <string>

class Vehicle {
public:
    virtual void printVehicle() = 0;
};
Java
public abstract class Vehicle {
    // Constructor to prevent direct instantiation
    private Vehicle() {
        throw new UnsupportedOperationException("Cannot construct Vehicle instances directly");
    }

    // Abstract method to be implemented by subclasses
    public abstract void printVehicle();
}
Python
from abc import ABC, abstractmethod

class Vehicle(ABC):
    @abstractmethod
    def print_vehicle(self):
        pass
JavaScript
class Vehicle {
    constructor() {
        if (new.target === Vehicle) {
            throw new TypeError("Cannot construct Vehicle instances directly");
        }
    }

    printVehicle() {
        throw new Error("Method 'printVehicle()' must be implemented.");
    }
}

2. Concrete Products

Concrete product classes representing different types of vehicles

C++
#include <iostream>
using namespace std;

class Vehicle {
public:
    virtual void printVehicle() = 0;
};

class TwoWheeler : public Vehicle {
public:
    void printVehicle() override {
        cout << "I am two wheeler" << endl;
    }
};

class FourWheeler : public Vehicle {
public:
    void printVehicle() override {
        cout << "I am four wheeler" << endl;
    }
};
Java
public class Vehicle {
    public void printVehicle() {
        // This method should be overridden
    }
}

public class TwoWheeler extends Vehicle {
    @Override
    public void printVehicle() {
        System.out.println("I am two wheeler");
    }
}

public class FourWheeler extends Vehicle {
    @Override
    public void printVehicle() {
        System.out.println("I am four wheeler");
    }
}
Python
class Vehicle:
    def print_vehicle(self):
        pass

class TwoWheeler(Vehicle):
    def print_vehicle(self):
        print("I am two wheeler")

class FourWheeler(Vehicle):
    def print_vehicle(self):
        print("I am four wheeler")
JavaScript
class Vehicle {
    printVehicle() {
        // This method should be overridden
    }
}

class TwoWheeler extends Vehicle {
    printVehicle() {
        console.log('I am two wheeler');
    }
}

class FourWheeler extends Vehicle {
    printVehicle() {
        console.log('I am four wheeler');
    }
}

3. Creator Interface (Factory Interface)

Factory interface defining the factory method

C++
#include <memory>

class Vehicle;

class VehicleFactory {
public:
    virtual std::unique_ptr<Vehicle> createVehicle() = 0;
};
Java
public interface VehicleFactory {
    Vehicle createVehicle();
}
Python
from abc import ABC, abstractmethod

class VehicleFactory(ABC):
    @abstractmethod
    def createVehicle(self):
        pass
JavaScript
class VehicleFactory {
    createVehicle() {
        throw new Error('Method not implemented.');
    }
}

4. Concrete Creators (Concrete Factories)

Concrete factory class for TwoWheeler

C++
#include <memory>

class Vehicle {
public:
    virtual ~Vehicle() {}
};

class TwoWheeler : public Vehicle {};

class FourWheeler : public Vehicle {};

class VehicleFactory {
public:
    virtual std::unique_ptr<Vehicle> createVehicle() = 0;
};

class TwoWheelerFactory : public VehicleFactory {
public:
    std::unique_ptr<Vehicle> createVehicle() override {
        return std::make_unique<TwoWheeler>();
    }
};

class FourWheelerFactory : public VehicleFactory {
public:
    std::unique_ptr<Vehicle> createVehicle() override {
        return std::make_unique<FourWheeler>();
    }
};
Java
public interface Vehicle {}

public class TwoWheeler implements Vehicle {}

public class FourWheeler implements Vehicle {}

public interface VehicleFactory {
    Vehicle createVehicle();
}

public class TwoWheelerFactory implements VehicleFactory {
    public Vehicle createVehicle() {
        return new TwoWheeler();
    }
}

public class FourWheelerFactory implements VehicleFactory {
    public Vehicle createVehicle() {
        return new FourWheeler();
    }
}
Python
from abc import ABC, abstractmethod

class Vehicle(ABC):
    pass

class TwoWheeler(Vehicle):
    pass

class FourWheeler(Vehicle):
    pass

class VehicleFactory(ABC):
    @abstractmethod
    def createVehicle(self):
        pass

class TwoWheelerFactory(VehicleFactory):
    def createVehicle(self):
        return TwoWheeler()

class FourWheelerFactory(VehicleFactory):
    def createVehicle(self):
        return FourWheeler()
JavaScript
class Vehicle {}

class TwoWheeler extends Vehicle {}

class FourWheeler extends Vehicle {}

class VehicleFactory {
    createVehicle() {
        throw new Error('Method not implemented.');
    }
}

class TwoWheelerFactory extends VehicleFactory {
    createVehicle() {
        return new TwoWheeler();
    }
}

class FourWheelerFactory extends VehicleFactory {
    createVehicle() {
        return new FourWheeler();
    }
}

Complete Code of above example:

C++
#include <iostream>
using namespace std;

// Library classes
class Vehicle
{
  public:
    virtual void printVehicle() = 0; // Abstract method
    virtual ~Vehicle()
    {
    }
};

class TwoWheeler : public Vehicle
{
  public:
    void printVehicle() override
    {
        cout << "I am two wheeler" << endl;
    }
};

class FourWheeler : public Vehicle
{
  public:
    void printVehicle() override
    {
        cout << "I am four wheeler" << endl;
    }
};

// Factory Interface
class VehicleFactory
{
  public:
    virtual Vehicle *createVehicle() = 0;
    virtual ~VehicleFactory()
    {
    }
};

// Concrete Factory for TwoWheeler
class TwoWheelerFactory : public VehicleFactory
{
  public:
    Vehicle *createVehicle() override
    {
        return new TwoWheeler();
    }
};

// Concrete Factory for FourWheeler
class FourWheelerFactory : public VehicleFactory
{
  public:
    Vehicle *createVehicle() override
    {
        return new FourWheeler();
    }
};

// Client class
class Client
{
  private:
    Vehicle *pVehicle;

  public:
    Client(VehicleFactory *factory)
    {
        pVehicle = factory->createVehicle();
    }

    Vehicle *getVehicle()
    {
        return pVehicle;
    }

    ~Client()
    {
        delete pVehicle;
    }
};

// Driver program
int main()
{
    VehicleFactory *twoWheelerFactory = new TwoWheelerFactory();
    Client twoWheelerClient(twoWheelerFactory);
    Vehicle *twoWheeler = twoWheelerClient.getVehicle();
    twoWheeler->printVehicle();
    delete twoWheelerFactory;

    VehicleFactory *fourWheelerFactory = new FourWheelerFactory();
    Client fourWheelerClient(fourWheelerFactory);
    Vehicle *fourWheeler = fourWheelerClient.getVehicle();
    fourWheeler->printVehicle();
    delete fourWheelerFactory;

    return 0;
}
Java
// Library classes
abstract class Vehicle {
    public abstract void printVehicle();
}

class TwoWheeler extends Vehicle {
    public void printVehicle()
    {
        System.out.println("I am two wheeler");
    }
}

class FourWheeler extends Vehicle {
    public void printVehicle()
    {
        System.out.println("I am four wheeler");
    }
}

// Factory Interface
interface VehicleFactory {
    Vehicle createVehicle();
}

// Concrete Factory for TwoWheeler
class TwoWheelerFactory implements VehicleFactory {
    public Vehicle createVehicle()
    {
        return new TwoWheeler();
    }
}

// Concrete Factory for FourWheeler
class FourWheelerFactory implements VehicleFactory {
    public Vehicle createVehicle()
    {
        return new FourWheeler();
    }
}

// Client class
class Client {
    private Vehicle pVehicle;

    public Client(VehicleFactory factory)
    {
        pVehicle = factory.createVehicle();
    }

    public Vehicle getVehicle() { return pVehicle; }
}

// Driver program
public class GFG {
    public static void main(String[] args)
    {
        VehicleFactory twoWheelerFactory
            = new TwoWheelerFactory();
        Client twoWheelerClient
            = new Client(twoWheelerFactory);
        Vehicle twoWheeler = twoWheelerClient.getVehicle();
        twoWheeler.printVehicle();

        VehicleFactory fourWheelerFactory
            = new FourWheelerFactory();
        Client fourWheelerClient
            = new Client(fourWheelerFactory);
        Vehicle fourWheeler
            = fourWheelerClient.getVehicle();
        fourWheeler.printVehicle();
    }
}
Python
from abc import ABC, abstractmethod

# Library classes
class Vehicle(ABC):
    @abstractmethod
    def printVehicle(self):
        pass


class TwoWheeler(Vehicle):
    def printVehicle(self):
        print("I am two wheeler")


class FourWheeler(Vehicle):
    def printVehicle(self):
        print("I am four wheeler")

# Factory Interface


class VehicleFactory(ABC):
    @abstractmethod
    def createVehicle(self):
        pass

# Concrete Factory for TwoWheeler


class TwoWheelerFactory(VehicleFactory):
    def createVehicle(self):
        return TwoWheeler()

# Concrete Factory for FourWheeler


class FourWheelerFactory(VehicleFactory):
    def createVehicle(self):
        return FourWheeler()

# Client class


class Client:
    def __init__(self, factory: VehicleFactory):
        self.pVehicle = factory.createVehicle()

    def getVehicle(self):
        return self.pVehicle

# Driver program


def main():
    twoWheelerFactory = TwoWheelerFactory()
    twoWheelerClient = Client(twoWheelerFactory)
    twoWheeler = twoWheelerClient.getVehicle()
    twoWheeler.printVehicle()

    fourWheelerFactory = FourWheelerFactory()
    fourWheelerClient = Client(fourWheelerFactory)
    fourWheeler = fourWheelerClient.getVehicle()
    fourWheeler.printVehicle()


if __name__ == "__main__":
    main()
JavaScript
// Library classes
class Vehicle {
    printVehicle()
    {
        throw new Error(
            "printVehicle() must be implemented");
    }
}

class TwoWheeler extends Vehicle {
    printVehicle() { console.log("I am two wheeler"); }
}

class FourWheeler extends Vehicle {
    printVehicle() { console.log("I am four wheeler"); }
}

// Factory Interface
class VehicleFactory {
    createVehicle()
    {
        throw new Error(
            "createVehicle() must be implemented");
    }
}

// Concrete Factory for TwoWheeler
class TwoWheelerFactory extends VehicleFactory {
    createVehicle() { return new TwoWheeler(); }
}

// Concrete Factory for FourWheeler
class FourWheelerFactory extends VehicleFactory {
    createVehicle() { return new FourWheeler(); }
}

// Client class
class Client {
    constructor(factory)
    {
        this.pVehicle = factory.createVehicle();
    }

    getVehicle() { return this.pVehicle; }
}

// Driver program
function main()
{
    const twoWheelerFactory = new TwoWheelerFactory();
    const twoWheelerClient = new Client(twoWheelerFactory);
    const twoWheeler = twoWheelerClient.getVehicle();
    twoWheeler.printVehicle();

    const fourWheelerFactory = new FourWheelerFactory();
    const fourWheelerClient
        = new Client(fourWheelerFactory);
    const fourWheeler = fourWheelerClient.getVehicle();
    fourWheeler.printVehicle();
}

main();

Output
I am two wheeler
I am four wheeler

Advantages

The Factory Method pattern provides flexibility and better design structure in object creation:

  • Encapsulates object creation logic, so clients don’t need to know how objects are created internally.
  • Promotes loose coupling by depending on abstractions instead of concrete classes.
  • Supports scalability and extensibility by allowing new product types without modifying existing code.
  • Improves reusability and maintainability by centralizing and reusing creation logic.

Limitations

Although useful, the pattern can introduce some complexity:

  • Increases the number of classes in the system.
  • Can make the code more complex compared to simple object creation.
  • May be unnecessary for small or simple applications.
Comment

Explore