Card 01/ 09

ConceptDifficulty: Intermediate2 min

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.

A long positional constructor and a builder

Without the patternevery part passed in order

java
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

java
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.

The creational family, with this pattern marked
PatternWhat it decides
Factory MethodWhich class a subclass creates, through one overridable method.
Abstract FactoryWhich family of related classes is created, through one object.
Builder (this topic)How a complex object is put together step by step.
PrototypeWhich existing object a new one is copied from.
SingletonThat a class has only one instance.
Builder

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