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.

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
#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;
}
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();
}
}
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()
// 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:

1. Product Interface
Product interface representing a vehicle
#include <iostream>
#include <string>
class Vehicle {
public:
virtual void printVehicle() = 0;
};
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();
}
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def print_vehicle(self):
pass
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
#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;
}
};
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");
}
}
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")
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
#include <memory>
class Vehicle;
class VehicleFactory {
public:
virtual std::unique_ptr<Vehicle> createVehicle() = 0;
};
public interface VehicleFactory {
Vehicle createVehicle();
}
from abc import ABC, abstractmethod
class VehicleFactory(ABC):
@abstractmethod
def createVehicle(self):
pass
class VehicleFactory {
createVehicle() {
throw new Error('Method not implemented.');
}
}
4. Concrete Creators (Concrete Factories)
Concrete factory class for TwoWheeler
#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>();
}
};
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();
}
}
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()
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:
#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;
}
// 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();
}
}
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()
// 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.