The Builder pattern is one of several well documented Creational patterns, unlike the others though it is primarily concerned with separating the complexity of creating an object from the object itself. As a developer concerned with making existing code more useable, readable and maintainable the Builder pattern provides a relatively easy way to implement restrictions on APIs that maybe too permissive.

The following are the two builder patterns I see the most, first the use of a simple method on your class:

int height, width;
Fence fence = new Fence.FromDimensions(height, length);

Or more to my liking a separate class responsible for the creation:

int height, width;
FenceBuilder fbuilder = new FenceBuiler(height, length)
Fence fence = fbuilder.Build();

I do find the use of the pattern to be a little troubling in smaller classes, because I tend to assume a simple constructor is fine. Additionally the need for a Builder pattern tells me that we may have identified inherent and unnecessary complexity in the class, and so devolving your class into simpler objects maybe the right way to go.

Given that I have a penchant for making changes to older code bases the cost of making wholesale changes can be high. The Builder pattern does provide for a less intrusive object building option that does not necessarily insist on a redesign. One of the traits I do look for is the existence of two or more constructors, but three constructors has become my personal tipping point.

There is, of course, a natural language limit you may reach where two or more signatures of a constructor can be in conflict even if you mean for your constructors to do quite different things, for example this would not be legal:

public class Fence
{
    public Fence(int height, int width){…}
    public Fence(int hypotenuse, int adjacent){…}
}

While you can imagine both constructors would perform vastly different calculations, both constructors have the exact same signature (two integers) and so compilation errors would ensue. For me the ideal Builder pattern would look something like this where we use object initializers (introduced in C# 3.0) :

Fence fence = new Fence.Builder{ Height = 6, Width = 20 }.Build();

We can make this happen with this class:

public sealed class Fence
{
    public int Height { get; private set; }
    public int Width { get; private set; }

    private Fence(Builder builder)
    {
        this.Height = builder.Height;
        this.Width = builder.Width;
    }

    public sealed class Builder
    {
        public int Height { get; set; }
        public int Width { get; set; }

        public Fence Build()
        {
            return new Fence(this);
        }
    }
}

I use this pattern quite a lot, that is:-

  • Make the constructor private, forcing the consumer to user your builder class.
  • Make the builder class nested in the object you want to create.

The second point makes this pattern interesting to me, as a class that is nested can access the private constructor of the container class. The obvious disadvantage of this implementation is that you have to repeat public properties in both the class you are constructing and the builder class.



Comment Section

Comments are closed.