skip to content

How does the Factory Method pattern differ from a simple factory (a static or helper method that switches on a parameter to build objects)?

level: middleimportance: must knowfreq 66%

answer

  1. switch = modify; override = extend
  2. static can't be overridden
  3. one file knows all products vs. each knows one
  4. data-driven selection → simple factory or registry
  5. registry = switch replaced by lookup table

basics

~20 s

A simple factory is one method with a switch that picks the class; adding a type means editing that method. Factory Method is an overridable method — adding a type means adding a new subtype that overrides it, leaving existing code untouched.

solid answer

~60 s

A *simple factory* (also called a static factory or "parameterized factory") centralizes creation in one place: `create(kind)` contains a conditional over all known kinds and returns the matching concrete class. It is not one of the GoF patterns; it is a useful idiom. Its extension mechanism is **modification** — a new product requires editing the switch, which violates the Open/Closed Principle and makes the factory a magnet for changes and a compile-time dependency on every concrete class. *Factory Method* uses **polymorphism** instead of a conditional: the creator declares an overridable `createProduct()` and each concrete creator supplies its own answer. Extension is by adding a subtype; the existing creator and business logic are not touched, and no single file depends on all products. Trade-off: the simple factory is far less code and easy to read when the set of products is small, closed, and centrally owned. Factory Method pays off when the set is open, when different contexts must vary the product, or when third parties extend the system. Note that a *static* factory can never be Factory Method, because static methods aren't overridable.

go deeper

for a junior

Say the difference plainly: a switch you edit vs. a method you override.

for a middle

Contrast extension mechanisms, name the Open/Closed implication, and note that static methods can't be overridden or easily substituted in tests.

for a senior

Discuss when each is appropriate, and present the registry hybrid for data-driven selection along with its runtime-failure and discoverability costs.

for a principal

Frame it as where the system's variation point and dependency direction live, who owns the product set (in-house vs. third-party plugins), and the long-term change-cost of a central switch as a coupling hot spot.

## Definitions first - **Simple factory / static factory**: a single function or static method, e.g. `Shape create(String kind)`, containing `if/switch` over known kinds and returning a concrete instance typed as the abstraction. Sometimes also used for *named constructors* (`Color.fromRgb(...)`, `List.of(...)`) whose purpose is naming, caching, or returning a hidden subtype rather than variation. - **Factory Method (GoF)**: an *overridable instance method* on a creator type; subtypes override it to choose the product. The creator itself contains logic that consumes the product. ## The core axis: conditional vs. polymorphism | Aspect | Simple factory | Factory Method | |---|---|---| | Selection mechanism | `if`/`switch` on a parameter or config value | Dynamic dispatch on the creator's runtime type | | Adding a new product | **Edit** the factory (open for modification) | **Add** a creator subtype (open for extension) | | Who knows all concrete classes | The factory file — it imports/depends on every product | Nobody centrally; each creator knows one product | | Where the decision is made | At each call site, via the argument | Once, at wiring time, by choosing the creator | | Extensible by third parties | Only if you add a registry | Yes — they subclass or supply their own creator | | Code volume | Minimal | One extra type per variant | | Testability | Can be hard to substitute if static | Easy: pass a test creator returning fakes | ## Why "static" matters Static (class-level) methods are resolved at compile time in most mainstream languages: they cannot be overridden, and in many they cannot be mocked without special tooling. That means a static factory is a hard dependency — code calling `ShapeFactory.create(...)` cannot be redirected without changing the code. Factory Method deliberately uses an *instance* method precisely so dynamic dispatch (or, in the delegation flavour, an injected collaborator) can redirect it. ## Where each is the right call **Prefer the simple factory when:** - The product set is small, stable, and owned by you (`Circle`, `Square`, `Triangle`). - Selection genuinely depends on runtime *data* (a string from JSON, a DB discriminator column) rather than on context — someone has to map data to a class, and one honest switch is clearer than a scattered hierarchy. - You want a *named constructor* for readability, caching, or returning a private implementation type. **Prefer Factory Method when:** - Different execution contexts must systematically produce different products (test vs. production, cloud A vs. cloud B, road vs. sea). - The creator has real logic that should be written once and reused across variants. - The product set is open-ended, especially to code you don't control. ## The hybrid people actually ship Most real systems land on a **registry**: a map from key → creator/supplier, populated at startup (explicitly, by dependency injection, or by a plugin discovery mechanism). Lookup is data-driven like a simple factory, but adding a product means *registering* rather than editing a switch — recovering Open/Closed while keeping runtime, data-driven selection. Understand this as "simple factory with the conditional replaced by a lookup table", and know its costs: registration order/duplicate-key issues, failures surfacing at runtime instead of compile time, and harder static reasoning about what exists. ## Common confusions to avoid - "Factory" is a general concept; "Factory Method" and "Abstract Factory" are two specific patterns. Saying "I used the Factory pattern" is imprecise. - Hiding a switch behind an instance method does **not** make it Factory Method if no subtype ever overrides it — the polymorphic variation point is the whole point. - A simple factory is not "wrong". YAGNI applies: introducing a hierarchy for a two-case switch that never grows is speculative generality.

  • If the concrete class must be chosen from a string coming out of a database row, does Factory Method still fit?
    Not directly — Factory Method varies by the creator's type, not by runtime data. Use a registry (map of key → creator/supplier) so lookup stays data-driven while new entries are added by registration rather than by editing a conditional.
  • Is a named static method like `Duration.ofSeconds(30)` an example of Factory Method?
    No. It's a static factory method — an idiom for readable, cache-friendly, subtype-hiding construction. It isn't overridable, so it provides none of the polymorphic variation Factory Method exists for.

saying these in an interview costs you the question

  • Calling any static `createX()` method "the Factory Method pattern".
  • Claiming the simple factory is always an anti-pattern; for a small closed set it's the simpler, better choice.
  • Saying the simple factory satisfies the Open/Closed Principle — adding a product means editing it.
  • Assuming Factory Method can select a class from a runtime string without an additional registry or a parameterized method.
  • Introducing a creator hierarchy for two variants that will never grow (speculative generality).

context