4

Head First Design Patterns only briefly describes the builder pattern in the appendix, without dedicating to it as much space as to other patterns.

Design Patterns: Elements of Reusable Object-Oriented Software treats it just like other design patterns.

Refactoring Guru also considers the builder pattern as a "true" pattern, without relegating it to an appendix.

Anyway, the first and the third sources put a strong focus, in my opinion, on how the pattern is useful to construct an object with just as many "ingredients" as the client wants.

In other words, a bad solution would be having a constructor like this

Ctor::Ctor(Param1* param1, Param2* param2, Param3* param3 /*, and many more */);

that needs to be called like this by a client who doesn't want to set the first two parameters

auto obj = Ctor(null, null, some_param3 /*, null, null */);

whereas the builder pattern would allow one to construct an object like this:

auto obj = Builder().setParam3(some_param3).build();

However, if all the builder pattern solved was the problem above, then I'd feel like named parameters would offer the same solution (and I'm not the only one to wonder about it). In turn, I'd have called the "builder pattern" the "named parameters pattern", that guides you to implement this feature in a language that lacks it.

Indeed, there are sources on the web that claim other languages don't need this pattern (or, if you like, the pattern is just less visible in them):

  1. here a convincing example of how Clojure's destructuring power just gives all you need as regards passing only the arguments you want to a constructor;
  2. a research engineer at Facebook (at least at the time he wrote this stuff), claims that Haskell's type classes and smart constructor are all you need to go on without the builder pattern, even though he doesn't go into any depth on the topic.

So, in view of the above point 1, my question is whether the builder pattern really offers more than a language feature like named parameters.

(I'm leaving point 2 out of the question because I'm not sure I've understood it.)

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    related: [Is the Builder design pattern obsolete in Python?](https://stackoverflow.com/q/40891995/1371329) – jaco0646 Jun 27 '22 at 01:28

1 Answers1

1

The builder pattern is a poor substitute for the optional named constructor parameters that some languages allow, or even the strongly typed "Props" literals that are often used in Typescript or similar.

There are two significant problems with it, compared to these other approaches:

  1. You have to write a builder class -- a lot of code that repeats things you already wrote in the class you're building; and

  2. There is no reasonable way to make the required parameters required.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • However, it's not hard to find sources claiming that the builder pattern can still be useful beside what the named parameters already offer. [Here](https://www.lihaoyi.com/post/OldDesignPatternsinScala.html#builder) a Scala example is given, and the author claims that _the builder is used to construct a relatively complex data structure that can't easily be passed as constructor arguments_. What do you think about that? – Enlico Jun 28 '22 at 05:44
  • I've also found [this question here on SO](https://stackoverflow.com/questions/22909717/is-this-monster-builder-a-good-builder-factory-pattern-for-abstracting-long-co) that features a builder pattern used to set an object in a non trivial way (mandatory parameters, as well as optional parameters, some of the latter ones conflicting with each other). – Enlico Jun 28 '22 at 06:00
  • 1) Sure, I wouldn't want to say that something like a builder is *never* useful. But I can certainly say that, while you *can* still write them in languages that allow optional named parameters, people generally don't. 2) Yes, I was careful to say "no reasonable way". It's not reasonable to put that much work into handling constructor arguments. – Matt Timmermans Jun 28 '22 at 12:19