A key to the understanding of the GoF design patterns is their intent. For the builder it is:
Separate the construction of a complex object from its representation
so that the same construction process can create different
When looking at the solution proposed by GoF, what strikes most is the separate building and assembly of parts: the structure distinguishes the
Director and the
Builder and enables a step by step construction:
- This aspect of the pattern apparently stroke Joshua Bloch as well, because his approach uses this separation to set a lot of optional parameters.
- This sequence of events also allows for validating parts before assembling the result, as you've notice in this XmlBuilder.
While being very useful, I think however that these examples focus only on one aspect of the pattern and miss the real intent. Thus their structure appears simplified by merging either
The missing intent
For GoF, it's not only about the separation between
Builder to build by step, but also the separation between
- If you look well at pattern structure, you'll notice that the
Builder provides the polymorphic/virtual
buildPart() methods. But
getResult() to obtain the final product is a method of
ConcreteBuilder that is not included in the abstract
Builder's interface. So it can use different parameters or return different types.
- The GoF sequence diagram on page 99 shows furthermore that a
Client calls the
Director for constructing the object and trigger the building of parts (perhaps using temporary objects), but that it's up to the client to call
getResult() directly from ConcreteBuilder.
- In fact, the client knows the ConcreteBuilder (may be even it instantiates it) and calls the
Director by referfencing it.
This makes clear that this pattern is not so for building the parts and assemble the whole (which after all is nothing more than a helper to simplify providing all the elements at once), but more for returning very different "representations" (classes) using the same procedure for constructing the parts.
Real life use of the complete pattern
The typical use in real life is to build composite objects having different types of implementation/representation, such as for example different graphical representations/views (e.g. Entity/Relationship or UML model), different input or output formats (e.g. JSON or XML document) or encodings (e.g ASCII vs UTF16/32).
A concrete use could for example be ADO.net with
DbCommandBuilder that is implemented by concrete
ODBCCommandBuilder to generate db specific commands.