2 minute read

Builder is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code.

The Builder pattern suggests that you extract the object construction code out of its own class and move it to separate objects called builders.

The pattern organizes object construction into a set of steps. To create an object, you execute a series of these steps on a builder object.

The important part is that you don’t need to call all of the steps. You can call only those steps that are necessary for producing a particular configuration of an object.

Some of the construction steps might require different implementation when you need to build various representations of the product.

In this case, you can create several different builder classes that implement the same set of building steps, but in a different manner.

Then you can use these builders in the construction process (i.e., an ordered set of calls to the building steps) to produce different kinds of objects.

When should you use it ?

  • Use the Builder pattern to get rid of a “telescopic constructor”.
  • Use the Builder pattern when you want your code to be able to create different representations of some product (for example, stone and wooden houses).
  • Use the Builder to construct Composite trees or other complex objects.

How do you implement it ?

  1. Make sure that you can clearly define the common construction steps for building all available product representations. Otherwise, you won’t be able to proceed with implementing the pattern.
  2. Declare these steps in the base builder interface.
  3. Create a concrete builder class for each of the product representations and implement their construction steps.
  4. Don’t forget about implementing a method for fetching the result of the construction. The reason why this method can’t be declared inside the builder interface is that various builders may construct products that don’t have a common interface. Therefore, you don’t know what would be the return type for such a method. However, if you’re dealing with products from a single hierarchy, the fetching method can be safely added to the base interface.
  5. Think about creating a director class. It may encapsulate various ways to construct a product using the same builder object.
  6. The client code creates both the builder and the director objects. Before construction starts, the client must pass a builder object to the director. Usually, the client does this only once, via parameters of the director’s constructor. The director uses the builder object in all further construction. There’s an alternative approach, where the builder is passed directly to the construction method of the director.
  7. The construction result can be obtained directly from the director only if all products follow the same interface. Otherwise, the client should fetch the result from the builder.