[EnhanceYourCode] : the Builder Pattern

Builder

Hello,

In this article, I’d like to present you the Builder pattern and how I use it in my C# code.

The Builder Pattern is a Creational design pattern, like the Factory Method Pattern I already covered un this previous article. Its main focus is to provide a light DSL to build objects by settings startup properties, by seperating the process of constructing an object from the object itself.

Basically, the idea is to create a class with mutable fields, that will be initialized with dedicated methods, and a final method that create the object itself from thoses values. Here is an abstract example :

using System;
namespace Builder
{
public class MyClass
{
private readonly string _aStringProperty;
private readonly bool _aGivenFlag;
private readonly bool _anotherFlag;
public MyClass(string aStringProperty, bool aGivenFlag, bool anotherFlag)
{
_aStringProperty = aStringProperty;
_aGivenFlag = aGivenFlag;
_anotherFlag = anotherFlag;
}
public object DoSomeBehavior()
{
dynamic @object = null;
@object.actionAt = DateTime.UtcNow;
@object.theName = _aStringProperty;
if (_aGivenFlag)
@object.theName = "the property : " + @object.theName;
if (_anotherFlag)
@object.theName = @object.theName.ToLower();
return @object;
}
}
}

This class is pretty straight forward : it’s an immutable object that perform some behavior. Nothing wrong here, but it’s construction elsewhere in the code can be a little painful, because we have to know how this class works internally to give the correct parameters to its constructor.

using System;
namespace Builder
{
public class MyPoorClassClient
{
public void ExecuteTheDefaultUseCase()
{
var myClass = new MyClass("the name to use", false, false);
var theResult = myClass.DoSomeBehavior();
}
public void ExecuteAnotherUseCase()
{
var myClass = var myClass = new MyClass("the first another one", true, true);
var theResult = myClass.DoSomeBehavior();
}
}
}

How can we enhance this construction, how can we make this kind of code more readable therefore more maintainable?
This is the purpose of the Builder Pattern. It will allow you to craft a nice and intent-revealing way to build your object :

using System;
namespace Builder
{
public class MyClassBuilder
{
private string _aNameToSet;
private bool _prependPropertyDescriptor = false;
private bool _lowerizeOutput = false;
public MyClassBuilder SetTheName(string aNameToSet)
{
_aNameToSet = aNameToSet;
return this;
}
public MyClassBuilder PrependPropertyDescriptor()
{
_prependPropertyDescriptor = true;
return this;
}
public MyClassBuilder LowerizeOutput()
{
_lowerizeOutput = true;
return this;
}
public MyClass Build()
{
return new MyClass(_aNameToSet, _prependPropertyDescriptor, _lowerizeOutput);
}
}
}

Note that all the builder’s methods return the builder itself, so we can compose a Fluent Interface that will improve the readability, again.

using System;
namespace Builder
{
public class MyClassClient
{
public void ExecuteTheDefaultUseCase()
{
var myClass = new MyClassBuilder()
.SetTheName("the first use case is simple")
.Build();
var theResult = myClass.DoSomeBehavior();
}
public void ExecuteAnotherUseCase()
{
var myClass = new MyClassBuilder()
.SetTheName("the first another one")
.PrependPropertyDescriptor()
.LowerizeOutput()
.Build();
var theResult = myClass.DoSomeBehavior();
}
}
}

Our code could now seem more than before, but we actually gain a lot of simplicity, and we don’t need to dive into the MyClass definition anymore to know how it behaves.

I will soon post a less theorical article about this pattern, keep in touch!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s