Skip to main content

Abstract Factory

What This Concept Is​

Abstract Factory is a creational pattern that defines an interface for creating a family of related products without binding clients to concrete classes. The guarantee it sells is consistency: every product returned by one factory instance belongs to the same family and is known to work together.

The structure is:

  • an AbstractFactory interface with one method per product kind (createButton, createScrollBar, createWindow)
  • concrete factories (MacFactory, WindowsFactory) that each return products from their own family
  • client code that holds an AbstractFactory and asks it for products without caring about the concrete family

The problem it absorbs: the client needs several products that must match (a Mac button belongs with a Mac scroll bar, never a Windows one), and the choice of family is made once, high in the call stack.

Why It Matters Here​

If Factory Method answers how does one method choose a product, Abstract Factory answers how do we keep an entire object graph in one consistent dialect. It is the canonical answer to cross-platform UI toolkits, multi-dialect database clients, and plugin ecosystems where mixing components from two families would be a correctness bug, not just a style issue.

It also has a sharp misuse story: if there is only one product kind or only one family, Abstract Factory is structural tax with no correctness win.

Concrete Example​

interface UIFactory {
createButton(): Button;
createScrollBar(): ScrollBar;
}

class MacFactory implements UIFactory {
createButton() { return new MacButton(); }
createScrollBar() { return new MacScrollBar(); }
}

class WinFactory implements UIFactory {
createButton() { return new WinButton(); }
createScrollBar() { return new WinScrollBar(); }
}

function buildUI(ui: UIFactory) {
const btn = ui.createButton();
const bar = ui.createScrollBar();
// guaranteed to match because ui is one instance
}

const factory: UIFactory = isMac() ? new MacFactory() : new WinFactory();
buildUI(factory);

Structural sketch:

          +--------------+              +----------+
| UIFactory |<-------------| Client |
| createButton | +----------+
| createScroll |
+--------------+
^ ^
| |
+---------------+ +---------------+
| MacFactory | | WinFactory |
+---------------+ +---------------+
| | | |
v v v v
MacBtn MacScroll WinBtn WinScroll

One factory is chosen once; all resulting products come from the same family.

Common Confusion / Misconception​

The most common confusion is Abstract Factory versus Factory Method:

  • Factory Method uses inheritance. A subclass overrides one method to pick one product.
  • Abstract Factory uses composition. A client holds a factory object with several related creation methods.

A subtler confusion is Abstract Factory versus Builder. Builder constructs one complex object step by step; Abstract Factory returns several simple objects that must be compatible.

How To Use It​

  1. Identify a set of products that must agree (all Mac, all Windows; all SQL, all NoSQL).
  2. Define an interface naming one creation method per product kind.
  3. Write one concrete factory per family.
  4. Inject the factory at the composition root; never let business code choose the family.
  5. If a new product kind gets added, every factory must change. Accept that cost only if the product family really is fixed.

Check Yourself​

  1. What correctness property does Abstract Factory protect that Factory Method does not?
  2. Why is adding a new product kind more painful than adding a new family?
  3. When is one enum plus a switch a better answer?

Mini Drill or Application​

Design an Abstract Factory for cross-platform file dialogs with two families (desktop, mobile). Implement:

  1. the DialogFactory interface with createOpenDialog and createSaveDialog
  2. two concrete factories returning platform-appropriate dialogs
  3. a client function that takes the factory as a parameter and never checks the platform

Then delete the interface and rewrite it as one createDialogs(platform) function. Compare readability.

Read This Only If Stuck​