factory method
A creational pattern
Create objects in a separate operation so that subclasses can override the way they're created.
PNG
SVG
hide notes
The factory method Design Pattern
Frequency
Complexity

The Factory Method might be the most frequent design pattern you will see during your career as a software developer.

This is mainly due to two of its main characteristics:

  • It solves a widespread use case. It enables you to extract the logic required to create an object from the location where the object will actually be instantiated.
  • It's straightforward to implement. All you need for this pattern are a few interfaces and one or two implementation classes. Depending on the paradigms supported by your language, implementing a function instead of a whole class can sometimes even be sufficient.

Let's first shed some light on the first point: What could be a reason for outsourcing the creation logic for an object? There are indeed some scenarios where this makes sense.

Extending an existing system

One prominent case for this pattern is its usage in frameworks or external libraries: These frameworks are usually closed systems exposing specific extension points through base classes or interfaces. Subclassing these extension points allows for adding custom logic for application-specific use cases.

For example, let's assume we build an application based on an external GUI framework. This framework has a class MenuItem representing an entry in our application's main menu. When clicking on the menu item, an action object is created, stored in an undo stack (for later undo/redo operations), and finally executed.

A framework providing base classes for menu items and actions.
A framework provides a base class for menu items.
Clicking on a menu item will execute an action.

The Action base class provided by the framework works as an extension point, and every application-specific code has to go into a subclass of this type.

The problem we now face is that since our subclass is not part of the framework, it does not know how to create an instance of our action when the user clicks on the menu item.

This is the point where the Factory Method pattern comes into play: The class MenuItem defines a factory method - createAction - which we have to override in a subclass to instantiate our custom action.

A custom menu item implementation provides a factory method to create a custom action.
Extending the framework with custom implementations.

And that's it: Thanks to this approach, we can extend an existing code base, like our GUI framework, without changing its implementation. The factory method lets us define how our objects are created, but the creation itself is deferred and controlled by the framework.

Flexibility

So far, we have provided our new factory method at compile time through subclassing, but we can even go one step further:

Nothing stops us from replacing our factory method also at runtime. We could, for instance, read an external configuration file that specifies which factory method to use and create different products depending on which configuration we have read.

This makes our system extremely flexible as it gives us complete control over all objects that get created - and that even after the application has already started!

But be careful to not overuse this strategy: This approach can quickly lead to overcomplicated systems where you spend more time editing cryptic XML configuration files than writing actual code. - seldomly a good trade.

Reduce Coupling

There is another noteworthy use case for the factory method - I would even consider it as one of its most valuable benefits: Its ability to reduce coupling.

Coupling is a term that describes how strongly two modules are connected and dependent on each other. A high degree of coupling is often considered problematic as changes to a single component must also be propagated to all its coupled counterparts, resulting in increased maintenance effort. It also means that the system loses flexibility because replacing one component or class with a different implementation is often not easily possible any more.

To understand how class coupling emerges, we must look at how objects are created in most OOP languages. Often, calling the new operator is all we have to do to execute the class constructor and instantiate a new object. What's important here to note is that we have to specify the concrete type of the object we want to create. We therefore create a dependency between the class making the new call (let's call it Client) and the class we create an instance from (our Product).

A Client class creating a Product.
Creating objects directly results in strong coupling between classes.

But our dependencies can go even deeper: If our Product depends on other types, our Client class now also depends on them - dependencies are always transitive. This can become challenging when you, for example, want to reuse an existing type and therefore wish to extract it into a separate base library. Suddenly, you recognize that your type depends on many others, and there is a cascade of classes you would also have to relocate. Some of them might even be system- or platform-specific implementations you actually wanted to keep out of your base module.

As we all know, a good way of reducing dependencies is by using interfaces instead of implementations. But the problem with interfaces is that we cannot instantiate them, and that's again where our factory method comes into play: We change our API to use interfaces in place of implementations, and instead of constructing objects directly, we use a factory method to reduce the coupling.

A client uses a factory method to create a product.
Using a factory method to reduce the coupling between Client and ConcreteProduct

Notice that there is no direct connection between our Client class and the ConcreteProduct class in the diagram, and thus also no coupling between them. Both could even be located in separate modules, if necessary.

Also note that we also did not implement the factory method directly in our Client class, but instead defined a separate Factory interface. Some might say this is a different design pattern, the so called Abstract Factory, but I wouldn't be too strict about that. Please see the FAQ section for the differences between these two patterns.

This way to remove coupling between classes becomes also very handy when writing unit tests. There, we often want to reduce external dependencies to ensure that our tests execute deterministically. For this, we can implement two different factory methods, one to construct objects with access to all external resources and another factory for creating test stubs with predefined behavior.

Production code replaced by test stubs via a factory method.
A factory method can be used to replace an object with external dependencies by a test stub.

In our production code, we use our production factory method (implemented by the ConcreteCreator) that creates our "real" objects, while for testing, we can switch to our product-stub factory (the StubCreator).

Improving Expressiveness

If flexibility or reduced coupling are no concerns for your use case, there is even the option to use a static factory method. Technically, the constructor of a class is also a (static) factory method, but it's relatively limited, as in most languages, its has to use a predefined name. So having two constructors with the same signature is not possible.

Using a static factory method instead does not have this limitation, as you can freely choose its name. Check, for example, this example (from the German Factory-Method Wikipedia page):

A Color class with two static factory methods.
Factory Methods can help where constructors are too limited.

Our Color class has two static factory methods with the same signature but with semantically different arguments. Such an implementation would not be possible using constructors alone.

Here, our goal is not to have more flexibility during runtime or reduce coupling. Instead, we aim to have a more expressive and convenient API for creating objects.

Implementation

Implementing this pattern in an OOP language is straightforward. We merely have to derive a subclass and override the factory method. If the base class contains other implementations, we can leave them untouched.

There is also the possibility of using only a single interface declaring the factory method. The logging framework log4j, for example, provides a LoggerFactory interface with a single factory method. To return a custom Logger object, one has to implement this interface and implement the corresponding method.

// log4j LoggerFactory
public interface LoggerFactory {
     Logger makeNewLoggerInstance(String name);
}

The reason the original pattern description is so OOP-centric may be historical, since, at the time it was first described, OOP was a very emerging concept. Today, most people would agree that using higher-order functions to implement this pattern would be much more convenient. However - while already known and used by functional languages - these kind of functions were less dominant among OOP languages of these times. Looking at some more recent frameworks or libraries, you can often see the more functional approach.

For example, Angular's dpendency injection mechanism expects a single factory function as a dependency provider. Instead of a complete implementation class, one can provide a single function the framework calls whenever a service instance must be created.

// Angular factory method for providing services
const heroServiceFactory = (logger: Logger, userService: UserService) =>
  new HeroService(logger, userService.user.isAuthorized);

export const heroServiceProvider ={ 
    provide: HeroService,
    useFactory: heroServiceFactory,
    deps: [Logger, UserService]
};

The dependency mechanism in the .NET framework works similarly. This extension method for registering services in the dependency service provider declares its last argument as a creator function that returns an object of the service type TService.

// .NET service registration via factory method
public static IServiceCollection AddSingleton<TService> (
    this IServiceCollection services, 
    Func<IServiceProvider,TService> implementationFactory) 
    where TService : class;

FAQ

Factory, Factory Method, Abstract Factory - What's the difference?

Technically, the Abstract Factory is a class consisting of several factory methods, each method responsible for creating a specific type of product. The idea is to group the creation of several related products together into one class. A factory method, on the other side, is more about creating only objects of a single type.

I like to compare the Abstract Factory with the barracks building in Warcraft (or similar real-time-strategy games): The facility provides different factory methods, one for creating a melee unit, another for creating distance fighters, and so on. Each faction has its own implementation of this building that produces faction-specific representations of these units, like the human foot soldier or the troll mage.

From a conceptual point of view, the Abstract Factory pattern delegates the construction to a different class, while the Factory Method pattern, on the other side, is only a single method within a class that might otherwise have a different purpose. Which approach to use best might depend on your concrete use case.

The term Factory, however, is not linked to any concrete pattern. It is often used to describe the general approach of delegating the creation logic of an object to another class. This includes both the Abstract Factory and the Factory Method, but also the purely functional approaches we've seen in the Implementation section.

Are there any pitfalls when using a Factory Method?

Thanks to its relatively easy structure, using the Factory Method is relatively safe. However, like most patterns, it increases your code's abstraction level. Instead of creating objects directly, you have to follow the factory method's implementation to determine which concrete type of object will be instantiated. This can become more difficult to figure out if your services and classes are registered through a dependency container.

Also, since your factory returns only an interface to your concrete product, your client code cannot access any methods specific to your implementation that are not part of the interface. If you require the concrete type of your product in your client, you might need to implement additional patterns, like, for example, the Visitor.

Regarding implementation, the classical OOP-centric approach, where the pattern is part of another class, might require some effort as one has to derive the entire class to implement a custom factory method. This can be avoided or at least simplified using the more functional-based approach where only a single creator function is required.