DEV Community

Discussion on: Builder Design Pattern

Collapse
 
mkuegi profile image
Markus Zancolò

I always wonder: why the need of an extra builder? Wouldn't it be sufficient to just add the "withTomato()" etc calls to the burger itself?

Collapse
 
qqlis profile image
Gregor K.

The builder pattern is very common when you use immutable value objects and you don't want any change to happen after object creation.
This example doesn't show it, but I would personally make all Burger attributes final, the BurgerBuilder an static inner class of Burger and the Burger(BurgerBuilder) constructor private.

Collapse
 
mkuegi profile image
Markus Zancolò

Good point. I had an other case in mind were the objects are created in different ways and may get additional fields set at a later stage.

Collapse
 
thomaswdmelville profile image
Thomas Melville • Edited

I've been learning about patterns for the last while, I have one thought on the static implementation. Making the builder class static could lead to concurrency issues.

Thread Thread
 
qqlis profile image
Gregor K.

No, just from the static keyword on a class you can't tell whether the class is thread safe or not.

The static keyword on a enclosed class means that the class is treated like a top-level class. It can be instantiated independently from the outer class and has no reference to an instance of the outer class.
A "real" non-static inner class can only be instantiated with an instance of the outer class and it will have access to the members of the outer class. This would not work for a Builder.

See also Java Language Specification §8.5.1:
docs.oracle.com/javase/specs/jls/s...

There could be concurrency issues if you would share the Builder instance with other threads. But this is independent from the Builder being static or not and it would be a quite unusual case to access the builder concurrently.

Thread Thread
 
thomaswdmelville profile image
Thomas Melville

Thanks Gregor,

In my case, the builder would be shared between threads so I could see the concurrency issue of using static. Automated user acceptance tests which execute in parallel in the same jvm.
I have the choice of making the builder thread safe or blocking users from instantiating the object without that builder.

Thread Thread
 
qqlis profile image
Gregor K.

Like I said making the builder a static inner class or a top-level class makes no difference regarding concurrency.

Each thread creates its own Builder object that is not shared between threads. Each thread fills it individually and calls build(). Afterwards you have a perfectly thread safe immutable object that you can make available to multiple thread.

The Builder object itself is not thread safe. But it doesn't need to be, since it should not be shared between threads. Sharing the Builder object between threads circumvents the whole point of this pattern and I would say its quite bad design.

So this is thread safe unless you use it in a unsafe way.

Thread Thread
 
thomaswdmelville profile image
Thomas Melville

I agree, the internals of the class (i.e. non final fields) would determine if it's thread safe or not.

I agree, in the case where the builder is static is not thread safe. Why shouldn't it be shared between threads though? My understanding of this pattern is that it's about object creation, in a way that makes the code more maintainable and reduces the chances of objects with incorrect state. I haven't seen any mention of concurrecny.

I've put 3 possible builder implementations in my pattern-play repo, as you may have guessed I use it for learning patterns
github.com/ethomev/pattern-play/tr...

I like the pattern where there is only one constructor for the object and it takes the builder. I think I will use this implementation the next time I need to use the builder pattern.

P.S. Sorry for the delay in replying, I'm now a father of 2 so I have less free time ;-)

Collapse
 
nishparadox profile image
Nishan Pantha

Yeah. That will be more concrete. The tutorial is just a rough pattern to get the insights.