DEV Community

Theodore Karropoulos
Theodore Karropoulos

Posted on • Edited on

Fluent Builder

Another way to implement the builder pattern is with fluent builder. Fluent builder provides a more readable and straightforward way to create objects. The pattern is implemented by having a series of methods that return the builder type itself and a build method that returns an instance of the class we are building.
For our example we are going to create a Desktop PC builder.

Bellow is the sample code:



public interface IDesktopBuilder
{
    IDesktopBuilder WithCase(string @case);
    IDesktopBuilder WithCpu(string cpu);
    IDesktopBuilder WithMotherBoard(string motherboard);
    IDesktopBuilder WithVideoCard(string videoCard);
    IDesktopBuilder WithOperatingSystem(string operatingSystem);
    Desktop Build();
}


Enter fullscreen mode Exit fullscreen mode


public class DesktopBuilder : IDesktopBuilder
{
    private readonly Desktop _desktop;

    public DesktopBuilder()
    {
        _desktop = new Desktop();
    }

    public IDesktopBuilder WithCase(string @case)
    {
        _desktop.Case = @case;
        return this;
    }

    public IDesktopBuilder WithCpu(string cpu)
    {
        _desktop.Cpu = cpu;
        return this;
    }

    public IDesktopBuilder WithMotherBoard(string motherboard)
    {
        _desktop.Motherboard = motherboard;
        return this;
    }

    public IDesktopBuilder WithVideoCard(string videoCard)
    {
        _desktop.VideoCard = videoCard;
        return this;
    }

    public IDesktopBuilder WithOperatingSystem(string operatingSystem)
    {
        _desktop.OperatingSystem = operatingSystem;
        return this;
    }

    public Desktop Build()
    {
        return _desktop;
    }
}


Enter fullscreen mode Exit fullscreen mode


public class DesktopPc
{
    public string Case { get; set; }
    public string Motherboard { get; set; }
    public string Cpu { get; set; }
    public string VideoCard { get; set; }
    public string OperatingSystem { get; set; }
}


Enter fullscreen mode Exit fullscreen mode

Finally we can create a Desktop PC by using the fluent builder by the following way



DesktopPc desktop = new DesktopBuilder()
    .WithCase("Mini Tower Case")
    .WithCpu("3.6Ghz 12 cores")
    .WithMotherBoard("Gaming board")
    .WithVideoCard("Gaming v3 12GB")
    .WithOperatingSystem("64bit OS")
    .Build();


Enter fullscreen mode Exit fullscreen mode

Or if we do not want to add an Operating System in our Desktop setup



DesktopPc desktop = new DesktopBuilder()
    .WithCase("Mini Tower Case")
    .WithCpu("3.6Ghz 12 cores")
    .WithMotherBoard("Gaming board")
    .WithVideoCard("Gaming v3 12GB")
    .Build();


Enter fullscreen mode Exit fullscreen mode

Progressive Builder (progressive interface)

Although the fluent builder pattern gives us a more readable way to create an object, there is a drawback with the above approach. We can't tie the way we construct the object, for example if there is a need to select motherboard before adding a CPU. Also even though we have already used a method, this method remains available and we can use it again as shown in the image bellow.

Image description

To achieve such a behavior we can utilize the Progressive Builder pattern. With progressive interface we can use multiple builder patterns in a sequential way. This allow us to chain in a fixed sequence the method calls. The advantage of this implementation is that we ensure that the object is built in the correct order.

For example we want to build a desktop pc but in the following order.

  • Select a case
  • Select a motherboard
  • Select a CPU
  • Select a video card
  • Select operating system

For this to be done we will create separate interface for each desktop property and everyone of them is going to have a returning type the interface that comes next in the chain.

Bellow is the sample code:



public interface IProgressiveBuilder
{
    ICaseBuilder WithCase(string @case);
}

public interface ICaseBuilder
{
    IMotherboardBuilder WithMotherboard(string motherboard);
}

public interface IMotherboardBuilder
{
    ICpuBuilder WithCpu(string cpu);
}

public interface ICpuBuilder
{
    IVideoCardBuilder WithVideoCard(string videoCard);
}

public interface IVideoCardBuilder
{
    IOperatingSystemBuilder WithOperatingSystem(string operatingSystem);
}

public interface IOperatingSystemBuilder
{
    ProgressiveDesktop Create();
}


Enter fullscreen mode Exit fullscreen mode


public class ProgressiveDesktop :
    IProgressiveBuilder,
    ICaseBuilder,
    IMotherboardBuilder,
    ICpuBuilder,
    IVideoCardBuilder,
    IOperatingSystemBuilder
{
    public string Case;
    public string Motherboard;
    public string Cpu;
    public string VideoCard;
    public string OperatingSystem;

    // Keep constructor private to avoid 
    // instantiation of the class outside of the builder
    private ProgressiveDesktop()
    {

    }

    public static IProgressiveBuilder Build()
    {
        return new ProgressiveDesktop();
    }

    public ICaseBuilder WithCase(string @case)
    {
        Case = @case;
        return this;
    }

    public IMotherboardBuilder WithMotherboard(string motherboard)
    {
        Motherboard = motherboard;
        return this;
    }

    public ICpuBuilder WithCpu(string cpu)
    {
        Cpu = cpu;
        return this;
    }

    public IVideoCardBuilder WithVideoCard(string videoCard)
    {
        VideoCard = videoCard;
        return this;
    }

    public IOperatingSystemBuilder WithOperatingSystem(string operatingSystem)
    {
        OperatingSystem = operatingSystem;
        return this;
    }

    public ProgressiveDesktop Create()
    {
        return this;
    }
}


Enter fullscreen mode Exit fullscreen mode


// Build desktop object with the use of progressive builder
ProgressiveDesktop desktop =  ProgressiveDesktop
            .Build()
            .WithCase("Mini Tower Case")
            .WithMotherboard("Gaming board")
            .WithCpu("3.6Ghz 12 cores")
            .WithVideoCard("Gaming v3 12GB")
            .WithOperatingSystem("64bit OS")
            .Create();


Enter fullscreen mode Exit fullscreen mode

Now when creating a progressive desktop the only available method is the Build.

Image description

Respectively the only available method after Build is the WithCase since this is the next in chain method.

Image description

Top comments (0)