Creational pattern
Factory Method
Let subclasses decide which concrete class to instantiate — the client only ever talks to a
common product interface, never to new ConcreteThing().
✗ The problem
Hard-coded
Hard-coded new behind a type switch
The client function knows about — and constructs — every concrete class itself. Add a platform → edit this function again.
function createButton(os) {
if (os === 'mac') return new MacButton();
if (os === 'win') return new WinButton();
// new platform? edit here again…
throw new Error('unknown os');
}
The client is coupled to every concrete product class, and this
switch grows forever — a straight Open/Closed violation.
✓ The pattern
↓
↑
Push the decision into a creator subclass
A creator declares a factory method; subclasses override it to return their
own product. The client only calls render() — it never names a concrete class.
class Dialog {
createButton() { /* overridden */ }
render() {
const btn = this.createButton();
btn.render();
}
}
class MacDialog extends Dialog {
createButton() { return new MacButton(); }
}
class WinDialog extends Dialog {
createButton() { return new WinButton(); }
}
Creator
createButton()
Button
interface: render()
MacButton
WinButton
✓ See it live
Pick a platform — the factory decides the class
The client code never changes. It just calls createButton(); the
concrete product that comes back depends on which factory it's talking to.
🍎
Mac
⊞
Windows
🌐
Web
no product yet
✓ Takeaway
Construction logic lives in one place
- Decouples the client from concrete product classes — it only knows the interface.
- Open/Closed: a new product = new class + new/registered creator, no client edits.
- Centralizes construction rules that would otherwise be scattered as
newcalls. - Careful: don't over-abstract for a single product type — that's YAGNI, a plain constructor is fine.
- Related: a simple factory is just a function with a switch (step 1, minus the pain); Factory Method uses subclass overrides; Abstract Factory creates whole families of related products.
🎯 Principle applied: Factory Method applies Dependency Inversion (clients depend on the product interface, not concrete classes) and Open/Closed (add a product = add a class, no client edits); construction gets its own single responsibility.
Back to all topics →