Card 03/ 09

CodeDifficulty: Intermediate3 min

Factory Method Template in Python, Java and TypeScript

The pure form with the Gang of Four's names and no domain, one participant at a time.

The Factory Method template is the pattern in its pure form, with the participant names from the class diagram and no domain to distract from the structure. This card builds it one participant at a time in Python, and the tabs then give the complete program in Python, Java and TypeScript, each with its output.

Building the template one participant at a time

Product

The interface every created object shares. In Python it is an abstract base class with one abstract method.

py
class Product(ABC):
    @abstractmethod
    def operation(self) -> str: ...

Concrete products

Two classes implement it, each answering operation in its own way.

py
class ConcreteProductA(Product):
    def operation(self) -> str:
        return "ConcreteProductA"

Creator

The creator declares the factory method and uses it. some_operation works with whatever the factory method returns, through the Product type alone.

py
class Creator(ABC):
    @abstractmethod
    def factory_method(self) -> Product: ...

    def some_operation(self) -> str:
        product = self.factory_method()
        return f"Creator worked with {product.operation()}"

Concrete creators

Each subclass overrides the factory method and names one concrete product. This is the only place a concrete product class is named.

py
class ConcreteCreatorA(Creator):
    def factory_method(self) -> Product:
        return ConcreteProductA()

The complete template

py
from abc import ABC, abstractmethod


class Product(ABC):
    @abstractmethod
    def operation(self) -> str: ...


class ConcreteProductA(Product):
    def operation(self) -> str:
        return "ConcreteProductA"


class ConcreteProductB(Product):
    def operation(self) -> str:
        return "ConcreteProductB"


class Creator(ABC):
    @abstractmethod
    def factory_method(self) -> Product: ...

    def some_operation(self) -> str:
        product = self.factory_method()
        return f"Creator worked with {product.operation()}"


class ConcreteCreatorA(Creator):
    def factory_method(self) -> Product:
        return ConcreteProductA()


class ConcreteCreatorB(Creator):
    def factory_method(self) -> Product:
        return ConcreteProductB()


for creator in [ConcreteCreatorA(), ConcreteCreatorB()]:
    print(creator.some_operation())
OutputRan with python:3.12-slim (Python 3.12.13)
Creator worked with ConcreteProductA
Creator worked with ConcreteProductB
The factory method's declaration, its one call, and the two overrides.
java
import java.util.List;

public class FmTemplate {
    public static void main(String[] args) {
        for (Creator creator : List.of(new ConcreteCreatorA(), new ConcreteCreatorB())) {
            System.out.println(creator.someOperation());
        }
    }
}

interface Product {
    String operation();
}

class ConcreteProductA implements Product {
    public String operation() {
        return "ConcreteProductA";
    }
}

class ConcreteProductB implements Product {
    public String operation() {
        return "ConcreteProductB";
    }
}

abstract class Creator {
    protected abstract Product factoryMethod();

    public String someOperation() {
        Product product = factoryMethod();
        return "Creator worked with " + product.operation();
    }
}

class ConcreteCreatorA extends Creator {
    protected Product factoryMethod() {
        return new ConcreteProductA();
    }
}

class ConcreteCreatorB extends Creator {
    protected Product factoryMethod() {
        return new ConcreteProductB();
    }
}
OutputRan with eclipse-temurin:21-jdk (Java 21.0.12)
Creator worked with ConcreteProductA
Creator worked with ConcreteProductB
Java makes the factory method `protected`, since only the creator and its subclasses call it.
ts
interface Product {
  operation(): string;
}

class ConcreteProductA implements Product {
  operation(): string {
    return "ConcreteProductA";
  }
}

class ConcreteProductB implements Product {
  operation(): string {
    return "ConcreteProductB";
  }
}

abstract class Creator {
  protected abstract factoryMethod(): Product;

  someOperation(): string {
    const product = this.factoryMethod();
    return `Creator worked with ${product.operation()}`;
  }
}

class ConcreteCreatorA extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProductA();
  }
}

class ConcreteCreatorB extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProductB();
  }
}

for (const creator of [new ConcreteCreatorA(), new ConcreteCreatorB()]) {
  console.log(creator.someOperation());
}
OutputRan with node:22-slim (Node 22.23.1), TypeScript 5.9.3
Creator worked with ConcreteProductA
Creator worked with ConcreteProductB
TypeScript's `protected abstract` says the same as Java's: subclasses must write it, and outside code cannot call it.

The highlighted lines are the whole pattern: the factory method is declared once, called once inside the creator, and overridden once per concrete creator. Everything else is ordinary classes.

The loop at the end holds two creators, and some_operation gives a different answer for each without changing: the shared code is written once, and the class it works with is chosen by which creator you have.