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

PatternKey Difference
Abstract-Factory-PatternAbstract 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 methodsOptional.of(), List.of() — static utility methods on a class; not a GoF pattern, no subclassing, no inheritance
Simple constructorWhen only one product type exists, a constructor is clearer — no pattern needed
ConceptRelationship
Abstract-Factory-PatternUses Factory Methods internally; creates product families instead of single products
Builder-PatternAlternative creational pattern for complex multi-step construction
Prototype-PatternAlternative when cloning is cheaper than construction
Singleton-PatternConcreteCreator 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