Mathematical Computerscientist, father and nerdy guy next door who loves to fix stuff.
I work as Technical Lead for Roomle and servant to my 18 month old son. Besides that... there is hardly enoug...
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.
Mathematical Computerscientist, father and nerdy guy next door who loves to fix stuff.
I work as Technical Lead for Roomle and servant to my 18 month old son. Besides that... there is hardly enoug...
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.
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.
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.
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.
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.
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 ;-)
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?
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.
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.
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.
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.
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.
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.
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 ;-)
Yeah. That will be more concrete. The tutorial is just a rough pattern to get the insights.