Fluent interfaces – Builder Pattern (2/2)

Previously I have introduced the concept of the builder pattern – in a very short way but it should have been clear what problem this pattern solves.

What we want to achieve by introducing the fluent interface is the code which will fulfill these assumptions:
– code will be easy to read,
– it will be easy to change,
– changes in the business object will be easy to introduce into the builder object,
– we can encapsulate some additional logic into building the object (e.g. additional associations to dependent objects, default values for required fields).

Each of these assumptions is important but the last one seems to be very common problem for plenty of real-life scenarios. In many cases every object must have the default value set, more importantly there are some objects which need to be created together with our business object.

Having these points in mind we can provide such code for our business object (see previous post):

class BusinessObjectFluentBuilder
{
    private int _id;
    private string _name;
    private IEnumerable<BusinessObject> _children;

    public BusinessObjectFluentBuilder WithName(string name)
    {
        this._name = name;

        return this;
    }

    public BusinessObject Build()
    {
        // some more sophisticated logic here
        return new BusinessObject { Name = _name };
    }
}

Be aware that I have simplified this code as much as possible (we can set only one property) – but this code is just a guidance, not the real life code. Such a builder allows building the object in such way.

var obj2 = new BusinessObjectFluentBuilder()
               .WithName("MyObject")
               .Build();

As you can see this code is easy to read. We have a builder object, we call method to set the name, and next we just call the Build to prepare us a required object. When the business object will get another property the only thing we need to do is to add one method into our builder to set such property. The difference in the building – we refactor Build method.

This way of implementation could be improved – we could skip the Build method in our implementation! Let’s have a look on another implementation of the fluent builder pattern.

class BusinessObjectFluentBuilderSecond
{
    private int _id;
    private string _name;
    private IEnumerable<BusinessObject> _children;

    public BusinessObjectFluentBuilderSecond WithName(string name)
    {
        this._name = name;

        return this;
    }

    public static implicit operator BusinessObject(BusinessObjectFluentBuilderSecond builder)
    {
        // some more sophisticated logic here
        return new BusinessObject { Name = builder._name };
    }
}

As you can see I have introduced the new operator – when we require object, the method is executed. For most of you it is easy to spot that this code has one disadvantage. For those of you who like the implicit typing this code won’t work properly. We have to use this object in such way:

BusinessObject obj3 = new BusinessObjectFluentBuilderSecond()
                          .WithName("MyObject3");

As you can see – in this place it is your choice how to implement it. Maybe even combine both versions into one – so you can use implicit (with Build() ) and explicit (without Build() ) programming paths.

Of course it is hard in cases when the new property is required – then refactoring becomes a nightmare. Of course this can be easy resolved – for example by throwing an exception in the Build method in case the new property is not set. It is also the interesting topic whether the builder object should be reusable – in the real world we do not need another builder to build another building. We re-use them. It is good to know that the builder object should permit the reset option – in such way we can reuse builder.

Most of the real-life objects are very complicated – especially when you use DDD (Domain Driven Design – http://goo.gl/rIOjN) and aggregate entities. For such scenarios you need to build objects as the connection between many. In such scenarios the builder patterns seems to be a good choice for the easy introduction of changes in the future.

Please leave a comment if you have a question.

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s