Factory Method Pattern
Factory Method Pattern
Define an interface for creating an object, but let subclasses decide which class to instantiate — deferring instantiation to subclasses.
Intent
The Creator class declares a factory method that returns a Product. Subclasses (ConcreteCreators) override the factory method to return a specific ConcreteProduct. Client code calls the factory method through the Creator interface and works with the Product interface — it never references a concrete class directly. This decouples the code that uses products from the code that creates them, allowing subclasses to vary the product type independently of the client.
When NOT to Use
- Only one concrete product type exists — a constructor is simpler and more explicit
- The type selection is fixed at compile time — a constructor parameter is clearer
- Subclassing is undesirable or the hierarchy is already deep — prefer composition
- The object to create is trivially simple — no construction logic to encapsulate
When to Use
- Client code must work with products but must not know which concrete class to create
- A library wants to let users extend its internal components via subclassing
- Subclasses should control which object gets instantiated in a hook-style framework
How It Works
Participants: Creator (abstract class with factory method), ConcreteCreator (overrides factory method), Product (interface or abstract class), ConcreteProduct (implements Product).
The factory method is the hook — the Creator's template methods call it; subclasses supply the concrete product. The Creator can provide a default implementation of the factory method that returns a default ConcreteProduct, which subclasses can optionally override.
Class Diagram
classDiagram
class Product {
<<interface>>
}
class ConcreteProduct {
}
class Creator {
<<abstract>>
+templateMethod()
+factoryMethod()* Product
}
class ConcreteCreator {
+factoryMethod() Product
}
Product <|.. ConcreteProduct
Creator <|-- ConcreteCreator
Creator ..> Product : creates
ConcreteCreator ..> ConcreteProduct : creates
TypeScript Example
// Factory Method — TypeScript
interface Transport {
deliver(): void;
}
class Truck implements Transport {
deliver() { console.log("Deliver by road in a box"); }
}
abstract class Logistics {
// Factory method
abstract createTransport(): Transport;
planDelivery() {
const t = this.createTransport();
t.deliver();
}
}
class RoadLogistics extends Logistics {
createTransport(): Transport { return new Truck(); }
}
// Usage
const logistics = new RoadLogistics();
logistics.planDelivery(); // "Deliver by road in a box"Java Example
// Factory Method — Java
interface Transport {
void deliver();
}
class Truck implements Transport {
@Override
public void deliver() { System.out.println("Deliver by road in a box"); }
}
abstract class Logistics {
// Factory method
public abstract Transport createTransport();
public void planDelivery() {
Transport t = createTransport();
t.deliver();
}
}
class RoadLogistics extends Logistics {
@Override
public Transport createTransport() { return new Truck(); }
}Confusion With
| Pattern | Key Difference |
|---|---|
| Abstract-Factory-Pattern | Abstract Factory creates a family of related products through multiple factory methods on a factory interface; Factory Method creates one product type via subclass override |
| Static factory methods | Optional.of(), List.of() — static utility methods on a class; not a GoF pattern, no subclassing, no inheritance |
| Simple constructor | When only one product type exists, a constructor is clearer — no pattern needed |
Related Concepts
| Concept | Relationship |
|---|---|
| Abstract-Factory-Pattern | Uses Factory Methods internally; creates product families instead of single products |
| Builder-Pattern | Alternative creational pattern for complex multi-step construction |
| Prototype-Pattern | Alternative when cloning is cheaper than construction |
| Singleton-Pattern | ConcreteCreator is sometimes a Singleton (prefer DI instead) |
Sources
- Gamma et al., Design Patterns, 1994, pp. 107–116 — authoritative definition and participants
- Bloch, Effective Java 3rd ed. — static factory method distinction (Item 1)
- refactoring.guru/design-patterns/factory-method — modern TypeScript framing