Category
Creational Patterns
Patterns that control how objects get built, so callers depend on what they need rather than on which concrete class supplies it.
What these patterns solve
Every new ConcreteThing() is a hard dependency. It fixes the class, the constructor arguments and often the lifetime of the object at the call site. Creational patterns move that decision somewhere else: into a method, an object, a step-by-step assembler or a copy of an existing instance. The caller asks for something that satisfies an interface and stops caring how it was made.
Reach for a creational pattern only when construction itself is the thing that varies or hurts. Most code should keep calling constructors directly.
Members
- Factory Method: a method, overridable in subclasses or passed as a function, decides which concrete product to create.
- Abstract Factory: one object creates a whole family of related products that must be used together, such as one cloud provider's storage, queue and secrets clients.
- Builder: assembles a complex object in named steps, so you never call a constructor with twelve positional arguments.
- Prototype: creates new objects by copying a configured instance instead of rebuilding it from scratch.
- Singleton: guarantees one instance of a class with a global access point. Usually better replaced by dependency injection.
How to choose within this category
- One product, and the concrete type depends on context: use Factory Method. In TypeScript, Python, Go or modern Java, a plain function that returns the interface (
createLogger(env)) is usually enough. Subclassing a creator class is rarely needed. - Several products that must match each other: use Abstract Factory. With only one product, it collapses into Factory Method.
- Many optional parameters or a multi-step, validated assembly: use Builder. In languages with named or default arguments (Python, Kotlin) or object literals (TypeScript), an options object often removes the need. Keep Builder for cases where order matters or the result must be validated before it exists.
- Construction is expensive or the configuration is only known at runtime: use Prototype. Check first that your language's copy tools (
structuredClone,copy.deepcopy, records withwith) don't already do the job. - Exactly one shared resource: create it once at the composition root and inject it. Treat Singleton as a last resort, because it hides dependencies and makes tests share state.
See Factory comparison for the differences between the factory variants.
Prefer no pattern when
- The concrete class never changes. Call the constructor.
- A module-level function or a dependency injection container already decides what to build.
- You're adding a factory "in case" a second implementation appears. Wait until it does; that urge is Speculative Generality.
See also
- Structural PatternsPatterns that combine objects and classes into larger structures while keeping each part replaceable and its interface small.
- Behavioral PatternsPatterns that assign responsibilities and route requests between objects, so behavior can change without rewriting the code that triggers it.
- Factory ComparisonTell apart a factory function, static creation method, simple factory, Factory Method and Abstract Factory, and pick the smallest one that fits.
- Choosing a PatternA decision guide that maps concrete code symptoms to the pattern that fixes them, and tells you when plain code beats any pattern.
Original writing and examples. Topic coverage follows Refactoring.Guru, which explains this topic with its own illustrations.