← Back to the blog

Patterns · video

Factory — design patterns

Factory and Abstract Factory: creating objects without naming the concrete class at the call site.

Video tutorial for this article · Open on YouTube ↗

A few words about two patterns, Factory and Abstract Factory. Both sit with the creational patterns and help you organize code once the object graph gets large.

Factory

The Factory pattern creates objects from one product family. You receive an object without naming the exact class that will be constructed.

Imagine you need many animals (a dog, a cat, a monkey, a horse). Each animal is its own class, and they share enough that those shared traits can live on an interface.

interface Animal {
    name: string;
    eat(): string;
    sleep(): string;
    run(): string;
}

Every animal has a name and three methods: eat, sleep, and run. The interface is only a shell. It does not say how the methods work. That definition belongs in the classes.

class Dog implements Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat(): string {
        return `Dog ${name} is eating`;
    }
    sleep(): string {
        return `Dog ${name} is sleeping`;
    }
    run(): string {
        return `Dog ${name} is running`;
    }
}
class Cat implements Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat(): string {
        return `Cat ${name} is eating`;
    }
    sleep(): string {
        return `Cat ${name} is sleeping`;
    }
    run(): string {
        return `Cat ${name} is running`;
    }
}

With the animal classes in place, we build the factory. The example is a shelter. Shelter declares an abstract addAnimal method. DogsShelter and CatsShelter extend it, so each one has to implement that method.

class Shelter {
    public abstract addAnimal(name: string): Animal;
}

class DogsShelter extends Shelter {
    public addAnimal(name: string): Dog{
        return new Dog(name);
    }
}

class CatsShelter extends Shelter {
    public addAnimal(name: string): Cat{
        return new Cat(name);
    }
}

What does this buy us?

Suppose Shelter also has methods that are not abstract. Every subclass can call them, and you do not implement them again. Or take a Button. Each screen styles its buttons differently, but a button is still a button and still does the same job. Each screen implements its own button factory, and you stop defining every button by hand.

Abstract Factory

I do not like treating Abstract Factory as a wholly separate pattern. The extra name adds noise for me. I split it simply: a Factory method is a method on a class that builds one general object. You reach for an Abstract Factory when the number of different objects grows. When you no longer want only a Button, but also a Form, a Checkbox, and a Link, those methods move into one abstract class. That class becomes responsible for creating the objects. You handed the responsibility over, and the main class got simpler.

← Back to the blog