Design Patterns – Do Named Arguments Replace the Builder Pattern?

builder-patterndesign-patterns

When using a language that supports named and optional arguments, does the builder pattern no longer have a practical use?

Builder:

new Builder(requiredA, requiredB).setOptionalA("optional").Build();

Optional/named arguments:

new Object(requiredA, requiredB, optionalA: "optional");

Best Answer

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.