Factory Method
Define an interface for creating an object, but let subclasses decide which class to instantiate — decouple creation from usage.
Intent & Description
🎯 Intent
Move object creation into a dedicated method so subclasses can override what gets created without changing how it’s used.
📋 Context
Your base class needs to create objects but doesn’t know (or care) which concrete type to instantiate. Maybe you’re building a logistics system where createTransport() should return a Truck, Ship, or Drone depending on the context.
💡 Solution
The Creator class defines a createProduct() factory method (usually abstract). Concrete Creator subclasses override it to return specific Product types. The rest of the Creator’s code calls createProduct() and works with the Product interface — never knowing the concrete type.
Real-world Use Case
Source
📌 TL;DR
Subclass decides what gets created. Caller works with the interface, never the concrete type. Extensible without modifying existing code. Subclass count grows as product types grow.
Advantages
- No tight coupling between the creator and concrete product types.
- Product creation is centralized — one place to change when the type changes.
- New product types plug in via new subclasses — existing code unchanged.
Disadvantages
- Every new product type needs a new Creator subclass — can proliferate quickly.
class Logistics {
planDelivery() {
const transport = this.createTransport();
return transport.deliver();
}
createTransport() {
throw new Error("Must implement createTransport");
}
}
class Truck { deliver() { return "Delivering by land in a box."; } }
class RoadLogistics extends Logistics {
createTransport() { return new Truck(); }
}
const logistics = new RoadLogistics();
console.log(logistics.planDelivery()); // "Delivering by land in a box."