7

Recently I shared with my team the Builder Pattern(fluent style) for unit testing.

I personally like to use that pattern for unit testing, since many objects are usually created and with different parameter configurations. The pattern helps keeping the unit tests short, specially if combined with Object Mother pattern.

Now some members of the team want to use it in other areas of the project, and it looks to me like it may spread everywhere...

What are the implications?

I understand that there is a cost on creating the Builders, but since we already have them, why not use them?

  • 6
    Why do you think it would be bad? What prompted you to ask this question, rather than agreeing with your colleagues that it would be useful in other parts of the codebase? – IMSoP Nov 27 '20 at 16:40
  • 1
    I don't disagree with them, I asked why would it be bad, and gave one reason why it would(the cost of creating Builders) and I also asked Why not use them since we already have them...), but whenever I study about design patterns I always hear "don't overuse them" "don't start your code with patterns", etc. So my problem is that just because I can not come up with reasons not to use it everywhere it doesn't mean that there is no reasons...which is the reason I'm asking here – LdN Nov 27 '20 at 17:54
  • The reason I asked is that it's a rather vague question: asking if there are any situations where it would be bad to use the Builder Pattern leads to a trivial "yes"; asking to list all of them leads to an open-ended list. A more useful question would describe the way you're planning to use it, and then you could ask if that was applying it correctly, or if there were dangers you hadn't spotted in your specific situation. – IMSoP Nov 27 '20 at 18:01
  • @IMSoP I can not entirely disagree with your opinion, maybe the community will decide to close the question for the reasons mentioned by you. But it's not uncommon to have examples on when not to use a pattern. I gave one. – LdN Nov 27 '20 at 18:11
  • 2
    @Juan: I think a more neutral wording could help to give the question a better reception and took the freedom to change it a little bit (you can undo my changes if you don't like them). – Doc Brown Nov 27 '20 at 19:26
20

Everyone wants a silver bullet that will let them turn off their brain. This isn’t it either.

Object construction, and its associated creational patterns, is a many and varied thing.

I presume you’re referring to Joshua Bloch’s builder pattern. This is fine when you want an immutable object and have a need to simulate named arguments because your language doesn’t have them.

But mastering Bloch’s builder is no excuse to ignore all the other creational patterns and techniques. Factory method, abstract factory, the GoF builder, hell even the much maligned singleton pattern all have situations where they should be considered.

And, believe it or not, Bloch’s Builder can even be outclassed in the realm of fluent construction. Study the eDSL pattern of construction and you’ll be able to enforce construction rules at compile time. Which is nice but takes a fair bit of work to set up and is not always needed.

You may like your shiny new hammer, but please don’t pretend everything is a nail.

  • I used the builder pattern in a similar style as can be seen in the accepted answer in stackoverflow.com/questions/59021513/… – LdN Nov 27 '20 at 18:28
  • 1
    "all have situations where they should be considered." Could you list a couple of examples to drive the point home? – Mast Nov 28 '20 at 9:56
  • 3
    The singleton pattern can be used when an immutable sentinel object is needed in an object-oriented language, or you otherwise need a pointer to a known “not real data” value other than NULL. – wizzwizz4 Nov 28 '20 at 12:14
  • I think the problem is less "wanting a silver bullet" and more in too many rules of the form "don't do this and that" when you have a situation before you where doing "that" seems like a good, easy idea. Too many things stated dogmatically. – The_Sympathizer Dec 20 '20 at 19:34
10

A pattern is only bad if it's not used properly or it's not fitting for the specific use case. Builder pattern is helpful to encourage immutability by using final modifiers on all the instance variables without having a super long constructor where everything has to be set, however, for objects with only a small number of heterogeneous fields it may be an overkill.

Also Mandatory + optional member fields is a feature of the Builder pattern described in Effective Java, however, it could also mean there is no way to tell at compile time if all necessary fields are set (you get NPE at runtime) --- so all necessary fields must be provided with default values to avoid this happens.

  • 1
    Since we already have the Builders, Why not use them? any disadvantage? – LdN Nov 27 '20 at 17:56
  • 5
    like I said about the pros/cons in the answer, it's not a yes/no option but more like how is it used in your case -- e.g, if there are redundant code compared with normal constructor(s), if someone forgets to include a filed in builder, how easy could the error being caught, etc – lennon310 Nov 27 '20 at 18:09
  • 1
    @Juan: Since you already have a bicycle, why not use the bicycle when you need to go to the kitchen? – Flater Nov 30 '20 at 14:20
  • @Flater Good point, though the world is full of people who takes the car to go to the gym and sit on a static bike... – LdN Nov 30 '20 at 14:45
4

You wrote

but since we already have them, why not use them?

so I guess you are talking exclusively about cases where you already implemented a Builder for unit testing, and now consider to reuse it outside of unit tests? That's probably fine, as long as you did not made any compromises regarding code quality because of some "it's just code supporting tests so it does not have to be clean"-mindset. The unit tests using the Builders then become automatically tests not just for the main "Subjects Under Test", but also for those Builders, so there is indeed no extra cost here.

Let me add that your literal question reads quite differently: the phrase "using a Builder everywhere" gives me the impression of someone introducing Builders for each and every class, even it they have zero or just one constructor parameter. That would be pretty useless overhead for no apparent benefit, and I think it is pretty self-evident why this does not make much sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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