Home Design Patterns Factory Method
Factory Method
Creational Gang of Four“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”
Gamma, Helm, Johnson & Vlissides, p. 107Purpose
A Factory Method is a method whose only job is to return a new object, placed
on a class so that a subclass can override it. The base class writes the useful
work in terms of an abstract product type and calls the factory method wherever
it would otherwise have called new. Which concrete class actually
turns up is then a decision the subclass makes.
The reason this needs a pattern at all is that new is not
polymorphic. Every other decision in an object-oriented program can be deferred
to a subclass by declaring a method; the choice of which class to instantiate
cannot, because constructors are not virtual. Factory Method is the workaround:
wrap the constructor call in something that is virtual.
Design
Two small hierarchies again, but this time they are joined by an override rather than a reference. The Creator declares the factory method, usually abstract, and calls it from an operation that contains the real behavior. Each ConcreteCreator overrides the factory method and returns a ConcreteProduct. The Creator's operation is written once and never mentions a concrete type.
anOperation() uses a Product without any arrow to
ConcreteProduct, and the only class that names ConcreteProduct is a single
overridden method.The base class may supply a default implementation rather than leaving the method abstract, which lets subclasses override only when they need something different. That is often the more practical choice, and it is what most frameworks do, because it means adding a new hook does not break every existing subclass.
Example
The Autobot Robotics vision system runs inspections that all follow the same outline: grab a frame, run a detector over it, decide pass or fail, record the result with the part's serial number. The only part that differs between a solder joint inspection and a barcode read is which detector runs.
The original code had a switch on inspection type inside the run
loop, which built the right detector. That worked fine and would have gone on
working, except for where the code lived. The run loop is in the shared vision
library, and the shared vision library is the component that gets qualified
against every customer's installed base before release. Adding a detector for one
customer meant editing a file that forced a full requalification for all of them,
which is measured in weeks, not in hours.
Moving the choice into createDetector() meant the shared loop
stopped changing. A new inspection type is now a new subclass in the customer's
own assembly. The shared code has not been touched since, which is exactly the
outcome that was wanted, and it had nothing to do with elegance.
abstract class InspectionRun
{
public void run(Frame f)
{
Detector d = createDetector(); // the factory method
Finding[] found = d.scan(f);
record(found);
}
protected abstract Detector createDetector();
void record(Finding[] found)
{
// shared, and it is the part that must not change
}
}
class SolderInspection : InspectionRun
{
protected override Detector createDetector()
{
return new SolderJointDetector();
}
}
class BarcodeInspection : InspectionRun
{
protected override Detector createDetector()
{
return new BarcodeDetector();
}
}
run(), and it names no
concrete detector. Each subclass contributes one line. That ratio, a lot of
shared behavior against a single point of variation, is the test for whether
this pattern fits.Seen in the Wild
The canonical example is iterator() on Java's
Collection: the interface promises an Iterator, and
every collection returns its own private implementation, which is why nothing
outside ArrayList has ever needed to know the name of its iterator
class. .NET does the same through IEnumerable.GetEnumerator(). In
ADO.NET, DbConnection.CreateCommand() is a factory method that each
provider overrides to return its own command type. Java's
URLStreamHandler.openConnection() is another: the protocol handler
decides which URLConnection subclass you get.
Comparisons
- Abstract Factory is the same idea scaled to whole families. Its creation methods are frequently factory methods, so the two are usually seen together rather than compared.
- Template Method is the pattern a Factory
Method almost always lives inside.
run()above is a template method, andcreateDetector()is one of its hooks. - Prototype solves the same problem without
subclassing the creator. If you are only subclassing in order to change one
new, cloning a configured instance may be cheaper. - Dependency Injection is the modern answer to most of what this pattern was for. Passing the detector in requires no subclass at all, and the choice moves out to the composition root.
- Singleton shares the "static method that
returns an object" shape, which is where a great deal of the naming confusion
comes from. A static
getInstance()is not a factory method in the sense meant here.
Why It Exists
My take
This pattern exists to patch a specific hole in C++ and the languages that followed it: there is no virtual constructor. Everything else about an object's behavior can be varied by a subclass. The one thing that cannot is the identity of the class you allocate, because by the time you are running you have already chosen. So we route the allocation through a method, because methods can be overridden and constructors cannot. Read that way, Factory Method is less a design insight than a language workaround that got promoted.
What makes it worth knowing anyway is where the pattern survives on merit:
the cases where the creating object genuinely owns the thing it creates.
collection.iterator() is not indirection for its own sake. Only the
collection knows how to walk itself, and the iterator's class is an
implementation detail that would be actively harmful to expose. That is a
different argument from "we might want to swap the implementation later", and
it is a much stronger one.
The name is the pattern's biggest problem. At least three distinct things
are called a factory method: this one, the static named constructor
(Integer.valueOf, LocalDate.of), and the "simple
factory" that switches on a string. Only the first is in the book. When someone
says a codebase is full of factory methods, they usually mean the third, and
they usually mean it as a complaint.
My practical rule is this: if you are creating a subclass whose only purpose is to override the factory method, you have written a very expensive constructor argument. Pass the thing in instead. The pattern earns its place when the subclass exists anyway and the creation choice is one of several things it varies.
Criticisms
Subclassing is a heavy tool for this job. To change which detector gets built, you inherit the creator's entire interface, its state, and its future changes. If that inheritance relationship is not something you would have wanted for its own sake, you have coupled two things permanently in order to vary one line, and you cannot undo it later without touching every subclass.
It also invites parallel hierarchies. One creator subclass per product subclass is the standard outcome, and now every new product means two new classes that must be kept in step by hand. Nothing in the language enforces the pairing, so the hierarchies drift, and the resulting bug is always the same: someone adds the product and forgets the creator.
Finally it is easy to apply reflexively. A factory method with exactly one implementation is not extensibility, it is a redirection with a comment attached promising that one day it will be useful. That day frequently does not arrive, and in the meantime every reader has to follow one more hop to find out what class they are actually holding.