Builders are most useful when your object needs a lot of arguments/dependencies to be useful, or you want to allow many different ways of constructing the object.
Off the top of my head, I can imagine someone might want to "build" objects in a 3D game like this:
// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
.syncWithOtherPlayers(serverIP)
.compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
.makeDestructibleRigidBody(health, weight)
...
I would argue this example is more readable with the builder methods I made up just now than it would be with optional parameters:
new Object(x, y, z, meshType: MESH.BLENDER,
meshPath: "./meshes/foo",
serverToSyncWith: serverIP,
vertexShader: "./shaders/foo.vert",
physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
health: health,
weight: weight)
...
In particular, the information implied by the builder method names has to get replaced by yet more parameters, and it's much easier to forget about one parameter in a group of closely related parameters. In fact, the fragment shader is missing, but you wouldn't notice that unless you knew to look for it.
Of course, if your object only takes one to five arguments to construct, there's no need to get the builder pattern involved, whether or not you have named/optional parameters.
A StringBuilder
is similar to a the Builder Pattern, but does not share much with the GoF description of this design pattern. The original point of the design pattern was
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
— from Design Patterns, by Gamma, Helm, Johnson, Vlissides.
(note: “complex” primarily means “composed of multiple parts”, not necessarily “complicated” or “difficult”)
The “different representations” is key here. E.g. assuming this construction process:
interface ArticleBuilder {
void addTitle(String title);
void addParagraph(String paragraph);
}
void createArticle(ArticeBuilder articleBuilder) {
articleBuilder.addTitle("Is String Builder an application of ...");
articleBuilder.addParagraph("Is the Builder Pattern restricted...");
articleBuilder.addParagraph("The StringBuilder class ...");
}
we might end up with a HtmlDocument
or a TexDocument
or a MarkdownDocument
depending on what concrete implementation is provided:
class HtmlDocumentBuilder implements ArticleBuilder {
...
HtmlDocument getResult();
}
HtmlDocumentBuilder b = new HtmlDocumentBuilder();
createArticle(b);
HtmlDocument dom = b.getResult();
So one central point of the Builder pattern is polymorphism. The Design Patterns book compares this pattern to the Abstract Factory:
Abstract Factory is similar to the Builder in that it too may construct complex objects. The primary difference is that the Builder pattern focuses on constructing a complex object step by step. […] Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
— from Design Patterns, by Gamma, Helm, Johnson, Vlissides.
This step-by-step aspect has then become the more popular aspect of the Builder pattern, so that in common parlance the Builder pattern is understood like this:
Split construction of an object into multiple steps. This allows us to use named arguments or optional parameters even in languages that do not support these features.
Wikipedia defines the pattern like this:
The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern and the factory method pattern whose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern[citation needed]. […]
The builder pattern has another benefit. It can be used for objects that contain flat data (html code, SQL query, X.509 certificate...), that is to say, data that can't be easily edited. This type of data cannot be edited step by step and must be edited at once. The best way to construct such an object is to use a builder class.[citation needed]
— from Builder Pattern on Wikipedia, by various contributors.
So as we can see, there is no truly common understanding of which pattern this name refers to, and in some points different definitions even contradict one another (e.g. regarding the relevance of polymorphism for Builders).
The only common property of the StringBuilder
with various interpretations of the pattern is that the product is created step by step rather than in one go. It does not meet a strict reading of the GoF definition of the design pattern, but please note that design patterns are malleable concepts meant to facilitate communication. I would continue to call StringBuilder
an example of the Builder Pattern, albeit an atypical one – the main reason for that structure in Java is performant concatenation in the presence of immutable strings, but not some interesting object-oriented design.
Best Answer
After looking at your other question I don't believe you are talking about the gang of fours builder pattern. I think you're talking about Josh Bloch's builder pattern.
It lets you write code like this:
The point here is to simulate named parameters in languages that don't have them natively. This allows the creation of an immutable value object with many fields without having to resort to setters or long unreadable constructors. Since the need for this is highly language dependent it really has nothing to do with anything Domain Driven Design talks about. If it did then certain languages couldn't be used for DDD. I think DDD would be fine with this so long as you use good names. So no, I don't think DDD prohibits use of builders.
Keep in mind, factory, builder, or
new
this is construction code. It shouldn't be casually mixed with your behavioral code.And of course you can use factories with builders to separate the concrete implementation from the more abstract formula.
I think this shows that the ubiquitous language can be made manifest in builders. Your domain expert should be able to read this just fine.