Factory pattern

Also known as: factory method

On this page 7

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.

VariantStructureTypical use
Simple factoryOne function or class with a conditional that picks the classChoosing among a few known implementations
Static factory methodA named static method on the class itself, such as of or fromReadable construction, caching or returning subtypes
Factory MethodA base class declares a creation method that subclasses overrideFrameworks that let subclasses decide the product
Abstract FactoryAn interface that creates a family of related objectsConsistent sets, such as all widgets for one UI theme
Registry-based factoryImplementations register under keys at startupPlugin systems and extensible formats
Main variants of the factory pattern

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.

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.

ConceptMain question it answersRelationship to factories
Dependency injectionWho supplies an object its dependenciesContainers often use factories internally to build objects
Builder patternHow to construct one complex object step by stepFactory picks the type, builder assembles the parts
Singleton patternHow to guarantee a single shared instanceA factory may return a cached singleton
Prototype patternHow to create objects by copying a templateAn alternative creation strategy to factories
Inversion of controlWho controls the flow and object lifecycleFactories are one mechanism that enables it
Factory pattern compared with related concepts

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.

SituationRecommendationReason
Concrete type depends on input or configurationUse a factoryKeeps selection logic in one place
Several related objects must matchUse an Abstract FactoryPrevents mixing incompatible families
Construction needs many steps or validationUse a factory or builderHides complexity and invariants
Tests need to substitute fake objectsUse a factory or dependency injectionAllows swapping implementations
One class, simple constructorCall the constructorA factory adds no value
Deciding whether a factory is justified

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.