Card 01/ 09
Builder Pattern: Building a Complex Object Step by Step
A constructor with twelve parameters, half of them None, is the problem a builder solves.
The Builder pattern moves the construction of a complex object into a separate builder object, which sets one part per call and returns the finished object from a final build(). This card covers the problem it solves, the intent, and when a builder is worth a second class.
The problem is called the telescoping constructor: a constructor that grows one parameter at a time as optional parts are added, until a call is a list of values whose meaning depends on their position.
Without the patternevery part passed in order
Report report = new Report(
"Weekly sales", null, "orders_by_day",
null, null, true, false, "Generated on Monday");Which null is the summary? Which true is the page numbers? The reader must count.
With the patternone named call per part
Report report = new ReportBuilder()
.title("Weekly sales")
.chart("orders_by_day")
.pageNumbers(true)
.footer("Generated on Monday")
.build();Each part is named where it is set, and parts left out are not written at all.
The Gang of Four state the intent as: separate the construction of a complex object from its representation so that the same construction process can create different representations. In most code today the first half matters more: a builder collects parts one call at a time, often chained, and build() is the single place that checks them and returns an object that is complete.
Think of ordering a sandwich at a counter: bread first, then each filling you ask for, then it is wrapped and handed over. The analogy breaks at the end. A counter never refuses a sandwich, while build() can refuse an object that is missing a required part, which is one of the reasons to have it.
Builder is one of five creational patterns, the family that controls how objects are created.
| Pattern | What it decides |
|---|---|
| Factory Method | Which class a subclass creates, through one overridable method. |
| Abstract Factory | Which family of related classes is created, through one object. |
| Builder (this topic) | How a complex object is put together step by step. |
| Prototype | Which existing object a new one is copied from. |
| Singleton | That a class has only one instance. |
Use it when
- An object has many optional parts, and a constructor call would be a row of values that only their position explains.
- The object is put together across several statements, such as conditions added one at a time in a loop.
- The finished object should not change, so every part must be set before it exists, and checked once.
Avoid it when
- The object has three or four parts, all required, and a constructor reads clearly.
- The language has named arguments with defaults, and nothing is assembled across statements.
← → move through sections and cards