Skip to main content

Factory Method

What This Concept Is

Factory Method is a creational pattern where a superclass defines the shape of a workflow but defers the decision of which concrete product to construct to a subclass or a pluggable creator.

The structure is:

  • an abstract Creator with a templated method that calls createProduct()
  • an abstract Product that the creator returns
  • concrete subclasses override createProduct() to pick the concrete Product

The problem it absorbs: a class needs to instantiate collaborators, but the concrete class varies by subtype, configuration, or subclass, and spraying new ConcreteX() through the base class would break the dependency rule.

Why It Matters Here

Most "this is hard to test" and "this will not extend" pain in object-oriented code traces back to a hard-coded new in the wrong place. Factory Method is the cleanest textbook answer to one specific version of that pain: when one class template is shared by many variants that differ only in which product they build.

It is also the first pattern where you have to resist reflex overuse. Factory Method is correct when there are multiple creator subclasses that already exist for other reasons. It is ceremony when there is exactly one creator and exactly one product.

Concrete Example

// Creator with a template method
abstract class PizzaStore {
Pizza orderPizza(String type) {
Pizza pizza = createPizza(type); // factory method
pizza.prepare();
pizza.bake();
pizza.box();
return pizza;
}
protected abstract Pizza createPizza(String type);
}

// Concrete creator picks concrete product
class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(String type) {
return switch (type) {
case "cheese" -> new NYCheesePizza();
case "pepperoni"-> new NYPepperoniPizza();
default -> throw new IllegalArgumentException(type);
};
}
}

Structural sketch:

       +--------------+                 +----------+
| Creator |<>-------------->| Product |
+--------------+ createProduct +----------+
| orderPizza() | ^
| createPizza()| |
+--------------+ |
^ |
| |
+--------------+ +-------------+
| NYPizzaStore |--------------->| NYPizza... |
+--------------+ createPizza +-------------+

orderPizza stays identical across stores; only createPizza changes. The base workflow is reused; the variation point is pushed to exactly one overridable method.

Common Confusion / Misconception

Learners collapse three distinct things into one "factory":

  • Simple Factory is not a GoF pattern. It is a static helper class that does a switch. Fine for small cases, not polymorphic.
  • Factory Method relies on inheritance. One method on a base class is overridden by subclasses.
  • Abstract Factory is an interface of multiple related factory methods, implemented as a standalone object.

If your creator has one method and one product and no inheritance story, a plain constructor or a function is usually better than Factory Method.

How To Use It

  1. Identify the class that is building something and cannot otherwise be reused because of that construction.
  2. Confirm there is genuine variation: more than one concrete product, chosen by more than one concrete creator.
  3. Extract the new ConcreteX() call into a protected abstract method on the creator.
  4. Let subclasses override the method, each picking the product it knows about.
  5. Delete the pattern if the second subclass never appears.

Check Yourself

  1. Why is Factory Method not the same thing as a static helper that returns an interface?
  2. What pressure makes the abstract method worth the inheritance cost?
  3. What does Factory Method lose compared to an injected factory object?

Mini Drill or Application

Take an existing class that constructs its collaborator with new. Do three things:

  1. Introduce an abstract create...() method and subclass once for the existing behavior.
  2. Add a second subclass that picks a different concrete product.
  3. Argue in two sentences whether the pattern actually pulled its weight, or whether an injected factory function would have been cleaner.

Read This Only If Stuck