Skip to content

Abstract Factory

Abstract Factory provides one interface for creating a family of related products without naming their concrete classes, guaranteeing the products you get always belong to the same family.

Consider a cross-platform UI kit. A window needs a button and a checkbox, and on every platform those widgets must look and behave consistently — a macOS button paired with a Windows checkbox would be wrong. The danger is mixing families: code that creates each widget independently can easily assemble an inconsistent set.

Abstract Factory solves this by promoting the whole family to a single interface. A GuiFactory declares createButton and createCheckbox; each concrete factory (MacFactory, WindowsFactory) returns widgets from exactly one platform. The application receives a factory once, then asks it for parts. Because every part comes from the same factory, they are guaranteed to match, and switching platforms means swapping one object.

Contrast with Factory Method. Factory Method is about one product chosen by subclassing and overriding a single method; the variation rides on inheritance. Abstract Factory is about a family of products selected by composing in a factory object; you typically hold a factory instance and call several creation methods on it. Put differently: Factory Method answers “which one?” through a subclass, while Abstract Factory answers “which set?” through a swappable object — and an Abstract Factory’s methods are often themselves factory methods.

classDiagram
  class GuiFactory {
    <<interface>>
    +createButton() Button
    +createCheckbox() Checkbox
  }
  class MacFactory {
    +createButton() Button
    +createCheckbox() Checkbox
  }
  class WindowsFactory {
    +createButton() Button
    +createCheckbox() Checkbox
  }
  class Button {
    <<interface>>
    +render() string
  }
  class Checkbox {
    <<interface>>
    +render() string
  }
  class MacButton
  class WindowsButton
  class MacCheckbox
  class WindowsCheckbox
  GuiFactory <|.. MacFactory
  GuiFactory <|.. WindowsFactory
  Button <|.. MacButton
  Button <|.. WindowsButton
  Checkbox <|.. MacCheckbox
  Checkbox <|.. WindowsCheckbox
  MacFactory ..> MacButton
  MacFactory ..> MacCheckbox
  WindowsFactory ..> WindowsButton
  WindowsFactory ..> WindowsCheckbox
Each concrete factory builds one consistent family of widgets
  • Abstract Factory (GuiFactory) — declares a creation method per product in the family.
  • Concrete Factories (MacFactory, WindowsFactory) — each produces a complete, internally consistent family.
  • Abstract Products (Button, Checkbox) — the interfaces the client depends on.
  • Concrete Products (MacButton, WindowsCheckbox, …) — the platform-specific implementations.
  • Client — receives a factory and builds its UI from the parts it returns, never naming a concrete class.

A GuiFactory that yields a matching button and checkbox per platform.

interface Button {
render(): string;
}
interface Checkbox {
render(): string;
}
class MacButton implements Button {
render() {
return '[ macOS button ]';
}
}
class MacCheckbox implements Checkbox {
render() {
return '[ macOS checkbox ]';
}
}
class WindowsButton implements Button {
render() {
return '[ Windows button ]';
}
}
class WindowsCheckbox implements Checkbox {
render() {
return '[ Windows checkbox ]';
}
}
interface GuiFactory {
createButton(): Button;
createCheckbox(): Checkbox;
}
class MacFactory implements GuiFactory {
createButton(): Button {
return new MacButton();
}
createCheckbox(): Checkbox {
return new MacCheckbox();
}
}
class WindowsFactory implements GuiFactory {
createButton(): Button {
return new WindowsButton();
}
createCheckbox(): Checkbox {
return new WindowsCheckbox();
}
}
function buildForm(factory: GuiFactory): string {
return `${factory.createButton().render()} ${factory.createCheckbox().render()}`;
}
console.log(buildForm(new MacFactory()));
console.log(buildForm(new WindowsFactory()));
  • Pro: products from one factory are guaranteed to belong to the same family — no mismatched combinations.
  • Pro: swapping the entire family is a one-line change: pass a different factory.
  • Pro: the client depends only on abstract product interfaces, never concrete classes.
  • Con: adding a new product to the family means changing the factory interface and every concrete factory.
  • Con: for a single product or single family it is heavier than Factory Method or a plain constructor.
  • Factory Method is the simpler one-product cousin and often implements each method of an Abstract Factory.
  • Singleton frequently holds the chosen factory so one instance is shared app-wide.
What does Abstract Factory primarily guarantee?
How does Abstract Factory differ from Factory Method?
What is the main cost of adding a brand-new product type to the family?