skip to content

Distinguish the GoF Factory Method pattern from a simple static factory method in Java. When is each appropriate?

level: seniorimportance: should knowfreq 50%

answer

  1. Static factory = one named `static` method, no hierarchy
  2. GoF = creator class + overridable createProduct(), varies by subclassing
  3. GoF pairs with Template Method (template calls the hook)
  4. Static factory: names, subtype return, instance control
  5. Modern alt to GoF: inject a Supplier<T> (composition)

basics

~20 s

A static factory is just a named static method that returns an object (like List.of). The GoF Factory Method is a pattern: a creator class has an overridable method that subclasses override to choose which product to build. Static factory = convenience; GoF = a hierarchy where subclasses decide the product.

solid answer

~50 s

A **static factory method** is a single `static` method (e.g. `Integer.valueOf`, `List.of`, `Optional.of`) that returns an instance — its value is a meaningful name, subtype-flexible return, and instance control, but there's no inheritance involved. The **GoF Factory Method pattern** is structural: an abstract or concrete *creator* declares a factory method (often `protected abstract Product create()`), and the variation point is *subclassing the creator* — each subclass overrides the method to instantiate a different concrete product, and the creator's template logic calls it without knowing the product type. So the GoF version achieves *polymorphic creation via inheritance*; the static version is a pragmatic alternative to a public constructor with no hierarchy. Use a static factory by default for cleaner creation APIs and instance control. Reach for the full GoF pattern when a framework superclass must defer the choice of object to subclasses (e.g. a base `Dialog`/`Application` whose `createButton()`/`createDocument()` subclasses override). In modern Java, lambdas and `Supplier<T>` often replace the GoF creator hierarchy.

go deeper

for a junior

Can identify that List.of(...) is a static factory method and that 'factory' means a method makes the object for you.

for a middle

Lists the advantages of static factory methods over constructors and recognizes the GoF version involves subclasses choosing the product.

for a senior

Cleanly separates the static-factory idiom from the GoF creator-subclass pattern, pairs GoF with Template Method, and picks the right tool per situation.

for a principal

Weighs the inheritance-based GoF creator against composition/DI alternatives (Supplier injection, frameworks), reasons about API evolution and extensibility, and guides when adding a creator hierarchy is justified versus over-engineering.

## Two things sharing a name The phrase "factory method" is overloaded in Java, and senior interviews want you to separate the two clearly. ### 1. Static factory method (the *Effective Java* idiom) This is simply a `static` method that returns an instance of (usually) its own class, used instead of a public constructor. Examples: `Integer.valueOf(int)`, `List.of(...)`, `Optional.of(x)`, `LocalDate.of(y, m, d)`. Its advantages over a constructor: - **Names.** `BigInteger.probablePrime(...)` is self-documenting, and you can have two factories with the same parameter list (impossible for constructors, whose signatures would collide). - **Subtype return.** It can return any subtype of its declared return type — even a non-public implementation class. - **Instance control.** It may return a cached/shared instance (Flyweight), enabling value semantics and singletons (`Boolean.valueOf`). - **Decoupling.** Callers depend on the returned interface, not a concrete class. It has *no inheritance dimension*. There is no "creator" hierarchy — it's one method. ### 2. GoF Factory Method (the *design pattern*) The Gang of Four define it as: *"Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses."* Structure: - A **Creator** (abstract or concrete) has business logic and declares a **factory method**, e.g. `protected abstract Product createProduct();`. - The Creator's other methods (a *template*) call `createProduct()` to obtain a Product, without knowing the concrete Product type. - **ConcreteCreator** subclasses override `createProduct()` to return a specific **ConcreteProduct**. The variation point is **inheritance of the creator**: to vary which product is made, you subclass the creator. This is *polymorphic creation*. It pairs naturally with the Template Method pattern (the creator's template calls the overridable factory hook). ```java abstract class Dialog { // Creator abstract Button createButton(); // factory method (the hook) void render() { // template logic uses the product abstractly Button b = createButton(); b.onClick(this::close); b.paint(); } void close() { /* ... */ } } class WindowsDialog extends Dialog { // ConcreteCreator Button createButton() { return new WindowsButton(); } } class HtmlDialog extends Dialog { Button createButton() { return new HtmlButton(); } } ``` `Dialog.render()` works for any concrete dialog; each subclass decides the concrete `Button`. The JDK's `java.util.AbstractList` and collection-framework skeletons use this template-plus-hook shape. ## Choosing between them - **Default to a static factory method** when you just want a cleaner, named, instance-controlled alternative to a public constructor for a single class. This is by far the more common need in application code (and what Effective Java Item 1 recommends considering first). - **Use the full GoF pattern** when a *framework/base class* must run shared logic but let *subclasses* choose the concrete collaborator it creates — i.e. you genuinely need polymorphic, inheritance-driven creation, typically in extensible libraries or frameworks. - **Consider a functional alternative.** In modern Java a `Supplier<Product>` or a `Function<Args, Product>` passed in (composition over inheritance) often replaces the creator hierarchy: instead of subclassing `Dialog`, you inject `Supplier<Button>`. This avoids a class explosion and is more flexible, at the cost of the explicit, named pattern structure. ## Common confusions to avoid - GoF Factory Method is **not** Abstract Factory. Abstract Factory is an *object* you hold that produces a *family* of related products through multiple methods; Factory Method produces *one* product and classically varies via subclassing, not a held factory object. - A static factory method is **not** literally the GoF pattern — it lacks the creator hierarchy — though it shares the "caller asks by intent" spirit and is what most Java developers mean colloquially.

  • How does Factory Method relate to the Template Method pattern?
    They compose: the creator's concrete template method runs the fixed algorithm and calls the abstract factory method (a hook) to obtain the product polymorphically. Template Method defines the skeleton; the factory method is one of its overridable steps that produces an object.
  • How would you replace a GoF creator hierarchy using modern Java features?
    Inject a `Supplier<Product>` (or `Function<Args, Product>`) into the creator via its constructor instead of subclassing. The creator calls `supplier.get()`; callers pass a lambda or method reference (e.g. `WindowsButton::new`). This is composition over inheritance and avoids a subclass per product.

saying these in an interview costs you the question

  • Treating 'static factory method' and the literal GoF Factory Method as identical — only the latter involves a creator subclass hierarchy.
  • Confusing GoF Factory Method with Abstract Factory (single product vs family of products).
  • Claiming the GoF pattern's variation point is a parameter switch — classically it is subclassing the creator.
  • Overusing a full creator hierarchy where a static factory or an injected Supplier would be simpler.

context