cv.cm

Coding · Design patterns

Factory Method pattern explained with examples

5 min read

Short answer

Factory Method is a creational design pattern that defines a method for creating an object but lets subclasses decide which concrete class to instantiate. The base class writes its logic against a product interface and calls the factory method, such as createTransport(), instead of new. This lets you add new product types by adding a subclass, without editing the code that uses the products.

Intent

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. It is one of the five creational patterns in the Gang of Four (GoF) book, and the only creational one that is class-scoped, because it relies on inheritance.

The problem it solves

Imagine a notification module. It formats a message, sends it, and logs the result. At first it only sends email, so the code calls new EmailChannel() directly. Then the product needs SMS, then push notifications. Every new channel means editing the same class and adding another if branch, even though the formatting and logging steps never change.

The sending workflow is stable; only the kind of channel varies. Factory Method moves the one varying decision, which class to create, into a single overridable method.

Structure and participants

ParticipantResponsibilityIn the example
ProductInterface of the objects the factory method creates.Channel
ConcreteProductImplements the Product interface.EmailChannel, SmsChannel
CreatorDeclares the factory method and contains logic that uses the product.Notifier
ConcreteCreatorOverrides the factory method to return a specific ConcreteProduct.EmailNotifier, SmsNotifier

TypeScript implementation

interface Channel {
  send(to: string, text: string): string;
}

class EmailChannel implements Channel {
  send(to: string, text: string): string { return `email to ${to}: ${text}`; }
}

class SmsChannel implements Channel {
  send(to: string, text: string): string { return `sms to ${to}: ${text.slice(0, 20)}`; }
}

abstract class Notifier {
  // The factory method: subclasses choose the concrete product.
  protected abstract createChannel(): Channel;
  // Shared logic that works with any Channel.
  notify(to: string, text: string): void {
    const channel = this.createChannel();
    const result = channel.send(to, text.trim());
    console.log("[log]", result);
  }
}

class EmailNotifier extends Notifier {
  protected createChannel(): Channel { return new EmailChannel(); }
}

class SmsNotifier extends Notifier {
  protected createChannel(): Channel { return new SmsChannel(); }
}

const notifiers: Notifier[] = [new EmailNotifier(), new SmsNotifier()];
for (const n of notifiers) n.notify("ada", " Your order has shipped today ");
// [log] email to ada: Your order has shipped today
// [log] sms to ada: Your order has shipp

Adding push notifications now means writing PushChannel and PushNotifier. The notify method, and every caller of it, stays unchanged.

Before applying the pattern, the creation decision was buried in the shared logic:

class Notifier {
  constructor(private kind: "email" | "sms") {}
  notify(to: string, text: string): void {
    // every new channel edits this method
    const result = this.kind === "email"
      ? `email to ${to}: ${text}`
      : `sms to ${to}: ${text.slice(0, 20)}`;
    console.log("[log]", result);
  }
}

A lighter alternative: pass a factory function

Factory Method uses inheritance. In TypeScript you often get the same flexibility with composition by passing a creation function into the constructor. This avoids one subclass per product:

interface Channel { send(to: string, text: string): string; }
class Notifier {
  constructor(private createChannel: () => Channel) {}
  notify(to: string, text: string): void {
    console.log("[log]", this.createChannel().send(to, text));
  }
}
const push = new Notifier(() => ({ send: (to, text) => `push to ${to}: ${text}` }));
push.notify("ada", "Hello"); // [log] push to ada: Hello

Use the subclass version when each creator already has its own class for other reasons, or when a framework expects you to extend a base class. Use the function version when the only difference between variants is the object they create.

When to use it, and when not to

Use Factory Method when:

  • A class contains a stable algorithm but cannot know in advance which concrete objects it must create.
  • You write a framework or library and want users to plug in their own product classes by subclassing.
  • You want to keep creation logic for a type in one place instead of scattering new calls.

Avoid it when:

  • There is only one product type and no real sign of a second one. A direct new is clearer.
  • The only reason is to make testing possible. Passing the dependency in through the constructor is simpler.
  • You would create a parallel hierarchy of creators that mirrors the products one to one with no other logic.

Real-world uses

  • Java collections: Iterable.iterator() is declared once, and each collection class (ArrayList, HashSet and others) overrides it to return its own iterator class. The GoF book describes this use of Factory Method for polymorphic iteration.
  • JavaScript iterables: every iterable implements [Symbol.iterator](), a method that returns a new iterator suited to that collection.
  • UI frameworks often let subclasses override a method that creates a component, a cell or a view, while the base class controls layout and life cycle.

Related patterns

PatternHow it differs
Abstract FactoryCreates a whole family of related products through an object with several creation methods. Its methods are often implemented as factory methods.
Template MethodFactory Method is frequently called from a template method, as notify calls createChannel above.
PrototypeCreates objects by copying an instance instead of subclassing the creator, so it needs no parallel creator hierarchy.
BuilderFocuses on constructing one complex object step by step, not on choosing which class to create.

FAQ

What is the difference between Factory Method and Abstract Factory?

Factory Method is a single method that subclasses override to create one product. Abstract Factory is an object with several creation methods that produce a family of related products that must be used together.

Is a simple factory function the same as Factory Method?

Not exactly. A function like createShape(kind) with a switch inside is often called a simple factory. The GoF Factory Method relies on a subclass overriding the creation method, but both hide new from the client.

Does Factory Method follow the open/closed principle?

Yes. You add a new product by adding a new product class and a new creator subclass, without changing the creator's existing logic.

Must the factory method be abstract?

No. The base class can provide a default implementation that returns a standard product, and subclasses override it only when they need something different.

All coding tutorials