Builder Pattern

What is the Builder pattern?

Builder means: you build an object step by step, setting only what you need, then call one method to get the finished object.

You do not write one giant constructor with many parameters. You chain small calls, then finish.

To build it you usually:

  1. Create a separate builder that collects values.
  2. Chain calls by returning the builder itself each time.
  3. Add one build() method that checks everything and returns the final object.

The problem it solves

Without a builder, an object with many optional pieces gets a constructor (or function) with a long, easy-to-misuse parameter list.

Add one more optional field, and every call site gets another slot to worry about — or you add another overload, and now there are three ways to build the same thing.

You want a way to say, in your own words: this computer has this CPU and this RAM — I don’t care about the rest.


The classic builder

A builder is a small helper object that collects values one at a time, then produces the finished object. Each setter returns the builder itself, so calls can chain onto one line.

Notice three things. Every setter returns the builder, so calls chain. The finished object’s fields are set once and never touched again. And build() checks the required fields before handing back an object, catching a mistake right away instead of downstream.


Worked example: assembling an order

A more realistic case: an order with a required id, a variable number of items, and an optional note.

Notice addItem can be called any number of times. A plain constructor cannot express that cleanly — you would have to hand it a whole list up front.


When it helps

Builder earns its place when an object has many fields, especially optional ones, and you want the finished object to be immutable. It also helps when you need to check a combination of fields together — easier once, inside build(), than across many constructor overloads.

The test: does this object have enough optional or many-combination fields that a single constructor call would be hard to read at a glance?


When it hurts

For a class with two or three required fields, a builder is pure overhead. new Point(10, 20) is already clear — wrapping it in a builder just adds lines that say nothing new.

A builder also does not fix a poorly designed object. If a class needs thirty configurable fields, ask whether it is doing too much and should be split up.


Practical tips

  • Give the builder a private target and a build() that returns the finished object.
  • Return the builder itself from every setter, for chaining.
  • Put all validation in build(), not scattered across setters.
  • Make the finished object immutable — no setters, only getters.
  • Reach for a builder only once a constructor needs four or more parameters, several optional.

Check your understanding

Builder in one line?
Build the object step by step, then finish with one call.

What problem does it solve?
It avoids long, error-prone parameter lists while keeping the result immutable.

What makes a builder “fluent”?
Every setter returns the builder itself, so calls chain: .cpu(...).ram(...).build().

Where should validation live?
Inside build(), so rules spanning multiple fields are checked together.

When is a builder overkill?
A small class with two or three required fields — a plain constructor is clearer.


What to learn next

Next: Prototype Pattern — instead of assembling an object piece by piece, start from an existing one and clone it.