6

I am currently learning about various object oriented design patterns. I came across a pattern called the builder pattern which is basically where you build a complex object through the use of creating simple objects that build on each other step by step.

My question is, in what scenarios would such a design pattern be appropriate? Which kind of tasks would benefit from such a design pattern?

4 Answers 4

5

Whenever creation of new object requires setting many parameters, and some of them (or all of them) are optional.

E.g. (for Java but you can easily transform to other language)

User.builder()
       .name("John")
       .age(30)
       .sex(Sex.MALE)
       .build()

instead of

User user = new User();

user.setName("John");
user.setAge(30); 
...

You can also easily create Objects for testing with such a builder e.g.

User maleUserOver30() {
   return User.builder()
                 .sex(Sex.MALE)
                 .age(31)
                 .build();
} 
9
  • 4
    This is called Bloch Builder. It's NOT a design pattern of GoF at all.
    – NingW
    Commented Apr 7, 2017 at 1:02
  • 1
    This answer will cause more people mis-understand what actually called a Design Pattern.
    – NingW
    Commented Apr 7, 2017 at 1:03
  • 1
    @N1ng I don't want to extend this discussion but I don't understand your arguments at all. The way I presented the builder pattern is the way it should be used in current moment - having a lot of benefits. The GoF book is neither a oracle not a up-to-date book. The same with wiki. And so called Bloch Builder is correct implementation of Builder pattern from GoF (think about it!). And about the post you mentioned - nothing spectacular there. Commented Apr 7, 2017 at 14:55
  • 1
    Maybe you should mention it a little bit. Then people who are new to/interested in design patterns of GoF won't get the wrong concept.
    – NingW
    Commented Apr 7, 2017 at 15:09
  • 3
    @N1ng Design patterns not equals GoF. They were used long before GoF. Commented Apr 7, 2017 at 20:00
10

To start I'll quickly contrast with the Factory Pattern. Both are used to abstract elements of object creation, however a factory pattern is most appropriate where the actual type of returned object is not known until runtime. If the type of the required object is known at design-time, I find factories to be inappropriate more often than not. However, the builder pattern is appropriate for single-type class creating, and many factories can encompass some elements of the builder pattern.

Where the builder pattern is most useful is when you are dealing with a situation where:

There are enough data fields that having them all in the constructor(s) is obnoxious, but you need the object to always be in a valid state.

The most obvious example is for immutable data types. If you have some data class that has dozens of properties/fields, especially if some of them optional, then putting all those in the constructor is going to be super annoying. On the otherhand, if you want that class to be immutable, you cannot instantiate an instance then modify a handful of properties. There are workarounds where you have a 'lock' method which afterwards makes properties read only, but that's annoying too. A builder is a good solution to the problem.

Similarly the builder that provide error checking/validation, or can provide alternative interfaces to the internal fields of the class, such as providing means to specify imperial or metric units or some such.

Even if the class is mutable, the builder pattern can still provide a means to make sure the class starts its life in a valid state, and the property updating methods can be used to maintain that validity as things are updated.

If you have mutable classes that only have to be in a valid state some of the time, such as a GUI widget that only has to be valid when the window is drawn, the builder pattern can lose a lot of its utility in those situations.

4

What I haven't seen mentioned in the answers above is the following. Using the builder pattern makes for cleaner code.

Cleaner code

Say you've created a library which exposes a POJO that's essential to the function of your library. The constructor of that POJO has one or two parameters which are essential. Now for a new feature that POJO needs another field that is essential. If you're not using the builder pattern you will need to add another parameter to the POJO's constructor.

Constructor nesting

To maintain backwards compatibility you will probably add a second constructor with three parameters and have the first constructor call the second constructor with some default value for the third parameter.

Something along the lines of:

constructor1(x,y){constructor2(x,y, "default")}

If you add a parameter a few times you will have a bunch of constructors you will need to maintain, have reduced the readability of your code and it makes for a confusing interface to someone who is new to your code-base.

Be gone constructor nesting!

If you use a builder, each time you want to add a parameter to the constructor, you simply add a method for said parameter and you're done. No clutter, easy to maintain and since it follows a specific pattern a new team-member will get the gist of it quite fast.

Don't use it for clean-code alone

Of course this doesn't apply when you don't expect the constructor to change. Which is quite the assumption but it's possible. So I would suggest that you look at the reasoning mentioned in the other answers first when you're considering the builder pattern.

Builder pattern as a sign of over-responsibility

Most likely if you're using the Builder pattern you've got a large amount of fields in your class. Meaning you may have added to much responsibility to that particular class. So you could also consider looking at the parameters you're passing. Whether you use a few of them in conjunction and if you do, create a new class that's responsible for handling any behaviour associated with those parameters. Then simply remove those parameters from the constructor and pass an instance of the new class to your original class [1] . There are down-sides to this but at least you've cleaned up your code and avoided introducing the Builder pattern needlessly.

TL:DR;

  1. The builder-pattern cleans up your code by eliminating the need for constructor-nesting.
  2. See if you can't introduce a parameter object before you introduce the builder pattern [1]. As wanting to introduce the builder pattern may be a sign of to much responsibility in one class.
  3. Don't introduce it just because "it's cleaner". It is. However, a constructor can be just as effective.
0

Here is another imagination exercise.

Building being a sequential activity implies builder in object oriented programming is a pattern to build objects sequentially. Complex logic of object construction is different than sequential build and is implemented using factory design pattern. The builder pattern is handy when at construction time there are multiple values to be encapsulated by the created object. The most obvious scenario for builder pattern I find is building an object with values retrieved in parallel from different sources, that is having several threads running in parallel retrieving values from different sources, passing them to the builder and once all the threads ended call the builder's method building the object.

That's what I think the builder is about, its implementation details being just details.

Not the answer you're looking for? Browse other questions tagged or ask your own question.