The factory pattern is a creational design pattern in which object creation is moved out of the calling code into a dedicated method or object, the factory, which decides which concrete class to instantiate and how to configure it. The caller asks for an object through an abstract type or interface and never names the concrete class. In software architecture and programming, the factory pattern is one of the most widely used ways to decouple code from concrete implementations.
The term covers a family of related techniques. The classic catalog of object-oriented design patterns describes two of them formally, Factory Method and Abstract Factory, while everyday practice also uses the simpler simple factory and static factory methods. All share one goal: a single place that knows how objects are built, so the rest of the system only knows what objects do.
How the factory pattern works
Without a factory, code that needs an object calls its constructor directly, which hard-wires a dependency on one concrete class. Every place that creates the object must know its constructor arguments, and adding a new variant means editing all of those places. A factory centralizes this knowledge behind a single call.
The factory receives whatever information is needed to choose a variant, such as a configuration value, a file extension or a platform name, and returns an instance typed as the common interface. Callers program against that interface, so a new implementation can be added by changing only the factory. This applies the open-closed principle from the SOLID principles: the system is open to extension without modifying its consumers.
A minimal example is a ParserFactory with a method create(format) that returns a JsonParser, XmlParser or CsvParser, each implementing a shared `Parser` interface. The import code calls factory.create(format).parse(data) and never refers to a concrete parser class.
Variants of the factory pattern
The variants differ in where the creation decision lives and in how many related objects are produced together. Choosing among them depends on how much flexibility the design actually needs.
| Variant | Structure | Typical use |
|---|---|---|
| Simple factory | One function or class with a conditional that picks the class | Choosing among a few known implementations |
| Static factory method | A named static method on the class itself, such as of or from | Readable construction, caching or returning subtypes |
| Factory Method | A base class declares a creation method that subclasses override | Frameworks that let subclasses decide the product |
| Abstract Factory | An interface that creates a family of related objects | Consistent sets, such as all widgets for one UI theme |
| Registry-based factory | Implementations register under keys at startup | Plugin systems and extensible formats |
The simple factory is not part of the formal catalog but is the most common form in practice. Factory Method relies on inheritance, while Abstract Factory relies on composition: client code receives a factory object and uses it to build matching products, which guarantees that objects from one family are never mixed with another.
Factory pattern and related architecture concepts
The factory pattern overlaps with several other concepts in software architecture, and confusing them leads to awkward designs. The table shows how it relates to its closest neighbors.
| Concept | Main question it answers | Relationship to factories |
|---|---|---|
| Dependency injection | Who supplies an object its dependencies | Containers often use factories internally to build objects |
| Builder pattern | How to construct one complex object step by step | Factory picks the type, builder assembles the parts |
| Singleton pattern | How to guarantee a single shared instance | A factory may return a cached singleton |
| Prototype pattern | How to create objects by copying a template | An alternative creation strategy to factories |
| Inversion of control | Who controls the flow and object lifecycle | Factories are one mechanism that enables it |
In modern codebases, dependency injection often replaces hand-written factories for wiring services at startup. Factories remain the right tool when the concrete type must be chosen at run time from data, such as a message type read from a network packet, which a container configured at startup cannot know in advance.
When to use a factory
A factory earns its place when object creation is variable, complex or likely to change. When a class has a single implementation and a trivial constructor, a factory only adds indirection.
| Situation | Recommendation | Reason |
|---|---|---|
| Concrete type depends on input or configuration | Use a factory | Keeps selection logic in one place |
| Several related objects must match | Use an Abstract Factory | Prevents mixing incompatible families |
| Construction needs many steps or validation | Use a factory or builder | Hides complexity and invariants |
| Tests need to substitute fake objects | Use a factory or dependency injection | Allows swapping implementations |
| One class, simple constructor | Call the constructor | A factory adds no value |
Static factory methods are a lightweight middle path. A method such as Duration.ofSeconds(30) has a descriptive name, can return a cached instance and can return a subtype hidden from the caller, none of which a constructor can do.
Common mistakes with factories
Factories are easy to overuse. The following mistakes appear frequently in code reviews and tend to make a system harder to read rather than more flexible.
- Speculative factories for classes that have only one implementation and no realistic second one.
- Growing switch statements that must be edited for every new type, instead of a registry.
- Factories that return concrete types, which defeats the purpose of hiding the implementation.
- Hidden global state when a factory caches objects without making the lifetime clear.
- Layers of factories creating factories, which obscure where objects actually come from.
A good factory is small, focused and easy to locate. If finding where an object is created requires following several levels of indirection, the design has likely gone beyond what the problem needs.
The idea in brief
The factory pattern means that one part of a program is responsible for making objects, and the rest of the program simply asks for what it needs. The requester does not have to know exactly which kind of object it receives, only what that object can do.
It is like ordering a coffee at a counter. You ask for a latte, and the staff decide which machine and beans to use. If the café buys a new machine, customers order exactly as before.
A practical scenario
A team builds a payment service that must support card payments, bank transfers and two digital wallet providers. Each method has its own client class with different setup steps, credentials and retry rules.
The team introduces a PaymentProcessorFactory that reads the payment method from the order and returns an object implementing a shared PaymentProcessor interface. Checkout code calls only process(order). When the business later adds a third wallet provider, developers write one new class and register it in the factory, and the checkout, refund and reporting modules require no changes at all.