The Abstract Factory Pattern and Why It's Just Factory Method Twice

Each method on an abstract factory is its own factory method, the products do not even need to be different types, and a hands-on exercise to try it yourself.

September 13, 20262 min read15 / 19

The last post built a UIFactory with createButton() and createLabel(), so a light theme and a dark theme could never get mixed up.

Here's the idea in one sentence: an abstract factory isn't a new mechanism, it's the factory method pattern used more than once inside the same factory.

Just Factory Method, Twice

Look at createButton() on its own. It's a method that decides which concrete Button to build, without the caller ever picking. That's exactly what a factory method is.

createLabel() is a second, completely separate factory method, living on the exact same factory. Nothing new happened here. Two ordinary factory methods just happen to sit on the same class.

That's the whole trick behind the name. An "abstract factory" earns its own name only because grouping factory methods together, so a matching set comes out every time, is useful enough to deserve one.

The Products Don't Even Have to Differ in Type

createButton() and createLabel() return different types, Button and Label. But that's not a requirement of this pattern, it's just how the theme example happened to work out.

Picture a factory with two methods that both return the exact same type, Button, but one returns a primary button and the other returns a secondary button, styled differently. That's still an abstract factory. What matters is that each method decides its own concrete instance, not that the methods return different types from each other.

Run this yourself: All code examples in this series are in the code-practice repo. Clone it, then run g++ -std=c++17 main.cpp -o main && ./main (C++) or npm start (TypeScript) to see it run.

Try It Yourself

A checkout page for a multi-tenant SaaS product needs to render a submit button and a price label, styled to match whichever customer's brand is currently active. Mixing one customer's button color with a different customer's label font would look broken.

  1. Design a BrandFactory interface with createSubmitButton() and createPriceLabel().
  2. Build SubmitButton and PriceLabel as shared product shapes.
  3. Build two concrete factories, AcmeBrandFactory and GlobexBrandFactory, each returning its own styled versions of both.
  4. Write a renderCheckout(factory) function that never mentions either brand by name, and confirm swapping the factory switches every piece together.

The Essentials

  1. Every method on an abstract factory is its own factory method. The pattern's only addition is grouping several of them on one factory so they build a matching set.
  2. The products a factory's methods return don't need to be different types. What matters is that each method independently decides its own concrete instance.