Skip to main content
replaced http://programmers.stackexchange.com/ with https://softwareengineering.stackexchange.com/
Source Link

So, it appears that the One Right Way of implementing a Builder Pattern in Java is to make the builder a nested typemake the builder a nested type (this isn't what this question is about though), and then make the product (the class of the object being built) take a dependency on the builder, like this:

I've been served the counter-argument (which is apparently explicitly defended in Bloch's book) that a builder pattern could be used to rework a type that would have a constructor bloated with dozens of optional arguments. So instead of sticking to what I thought I knew I researched a bit on this site, and found that as I suspected, this argument does not hold waterthis argument does not hold water.

So what's the deal? Why come up with over-engineered solutionsover-engineered solutions to a problem that shouldn't even exist in the first place? If we take Joshua Bloch off his pedestal for a minute, can we come up with one single good, valid reason for coupling two concrete types and calling it a best practice?

So, it appears that the One Right Way of implementing a Builder Pattern in Java is to make the builder a nested type (this isn't what this question is about though), and then make the product (the class of the object being built) take a dependency on the builder, like this:

I've been served the counter-argument (which is apparently explicitly defended in Bloch's book) that a builder pattern could be used to rework a type that would have a constructor bloated with dozens of optional arguments. So instead of sticking to what I thought I knew I researched a bit on this site, and found that as I suspected, this argument does not hold water.

So what's the deal? Why come up with over-engineered solutions to a problem that shouldn't even exist in the first place? If we take Joshua Bloch off his pedestal for a minute, can we come up with one single good, valid reason for coupling two concrete types and calling it a best practice?

So, it appears that the One Right Way of implementing a Builder Pattern in Java is to make the builder a nested type (this isn't what this question is about though), and then make the product (the class of the object being built) take a dependency on the builder, like this:

I've been served the counter-argument (which is apparently explicitly defended in Bloch's book) that a builder pattern could be used to rework a type that would have a constructor bloated with dozens of optional arguments. So instead of sticking to what I thought I knew I researched a bit on this site, and found that as I suspected, this argument does not hold water.

So what's the deal? Why come up with over-engineered solutions to a problem that shouldn't even exist in the first place? If we take Joshua Bloch off his pedestal for a minute, can we come up with one single good, valid reason for coupling two concrete types and calling it a best practice?

Tweeted twitter.com/StackProgrammer/status/728433175765000192
Source Link

Why would a type be coupled with its builder?

I've recently deleted a answer of mine on Code Review, that started like this:

private Person(PersonBuilder builder) { 

Stop. Red flag. A PersonBuilder would build a Person; it knows about a Person. The Person class shouldn't know anything about a PersonBuilder - it's just an immutable type. You've created a circular coupling here, where A depends on B which depends on A.

The Person should just intake its parameters; a client that's willing to create a Person without building it should be able to do that.

I was slapped with a downvote, and told that (quoting) Red flag, why? The implementation here has the same shape that which Joshua Bloch's demonstrated in his "Effective Java" book(item #2).

So, it appears that the One Right Way of implementing a Builder Pattern in Java is to make the builder a nested type (this isn't what this question is about though), and then make the product (the class of the object being built) take a dependency on the builder, like this:

private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; } 

https://en.wikipedia.org/wiki/Builder_pattern#Java_example

The same Wikipedia page for the same Builder pattern has a wildly different (and much more flexible) implementation for C#:

//Represents a product created by the builder public class Car { public Car() { } public int Wheels { get; set; } public string Colour { get; set; } } 

As you can see, the product here does not know anything about a Builder class, and for all it cares it could be instantiated by a direct constructor call, an abstract factory, ...or a builder - as far as I understand it, the product of a creational pattern never needs to know anything about what's creating it.

I've been served the counter-argument (which is apparently explicitly defended in Bloch's book) that a builder pattern could be used to rework a type that would have a constructor bloated with dozens of optional arguments. So instead of sticking to what I thought I knew I researched a bit on this site, and found that as I suspected, this argument does not hold water.

So what's the deal? Why come up with over-engineered solutions to a problem that shouldn't even exist in the first place? If we take Joshua Bloch off his pedestal for a minute, can we come up with one single good, valid reason for coupling two concrete types and calling it a best practice?

This all reeks of cargo-cult programming to me.