Factory method Design Pattern

Last Updated : 4 May, 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 where you need to send different types of notifications like Email, SMS, or Push notifications. Instead of creating objects directly, you use a Factory Method to decide which notification to create.

notificationfactory
Factory Method Design Pattern

In the Diagram:

  • If user selects Email - create EmailNotification
  • If user selects SMS - create SMSNotification
  • If user selects Push - create PushNotification

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.

  • Web Browsers (e.g., Chrome, Firefox): Browsers use factory methods to create different types of plugins or page renderers based on content type (e.g., PDF, HTML, Flash). This allows flexible and extensible handling of various media.
  • Android OS (Activity Instantiation): In Android, activities are often created using factory methods internally to manage lifecycle and resource setup. Developers override methods like onCreate() while the system handles object creation.
  • Payment Gateways (e.g., Stripe, PayPal): E-commerce platforms use factory methods to create different payment processors. Based on user selection, the factory returns an instance of the correct payment service without changing client logic.
  • Game Development (e.g., Unity, Unreal Engine): Games use factory methods to spawn enemies, items, or NPCs dynamically based on game level or environment. This decouples object creation from the game logic and enables easy scalability.

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

  • Tight coupling: Client depends directly on product classes.
  • Violation of SRP: Client handles both product creation and usage.
  • Hard to extend: Adding a new vehicle requires modifying the client.

Solutions to the Problems

To address issues with direct object creation and conditional logic in clients, the Factory Method pattern provides a structured approach:

  • 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

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.

Disadvantages

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