How to design a Fluent Interface

Martin Fowler coined the term “FluentInterface” to describe objects that expose an interface that flows, and is designed to be readable and concise.  The cost of this fluency is additional effort required to design the interface for your object and the slight increase in complexity.  These types of interfaces are often utilized to create configurations for your objects but can progress into an internal Domain Specific Language or DSL.

Configuration Fluent Interface Example: (sometimes called Method Chaining)

Order
    .AddFreeShipping()
    .IncludeItem(10)
    .SetQuantity(2);

DSL Fluent Interface Example:  (Rhino Mocks) 

Expect
    .Call(entityMock.GetID(12))
    .IgnoreArguments()
    .Repeat
    .Once()
    .Return(entityDataSet);

Show me the Code


Fluent interfaces are best explained by showing some code examples, so I’ll take the rather prosaic Person object and create a fluent interface for it.   

Take a common Person object and write some code to instantiate and Initialize the object

public class Person
{
    private string _firstName;
    private string _lastName;
    private int _age;
    public bool _isActive;

    public Person(string firstName, string lastName, int age, bool isActive)
    {
        _firstName = firstName;
        _lastName = lastName;
        _age = age;
        _isActive = isActive;
    }

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }

    public bool IsActive
    {
        get { return _isActive; }
        set { _isActive = value; }
    }
}

This is a common pattern where the constructor is used to quickly set the properties of the class.  The initialization code would look something like this.

Person person = new Person("Frank", "Pat", 30, true);

Although this code is concise it is not very readable. Is “Frank” the first name or the last name? What does the value true represent? The readability issue becomes more problematic as the number of construction parameters increase.  One solution, and the point of this post, is to write a Fluent Interface for our Person class.  The idea here is to allow each property to be set through a method call and then have that method return a reference to itself so you can continue on with next method call (often called method chaining).

person.SetLastName("Frank").SetFirstName("Pat");

This makes our code concise and far easier to read, we now know that “Frank” is the last name.  However, an obvious issue with this pattern is that we are now cluttering up our class with methods that, when taken out of context, make little sense.  We have a FirstName property and a SetFirstName method defined on our class that obfuscates the intent. A better approach is to create an internal class that is accessed through a Set property and exposes only the Fluent Interface.

 

public class Person
{
    public Person()
    {
        _set = new PersonFluentInterface(this);
    }

    private string _firstName;
    private string _LastName;
    private int _age;
    private readonly PersonFluentInterface _set;
    private bool _isActive;

    public PersonFluentInterface Set
    {
        get { return _set; }
    }

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName
    {
        get { return _LastName; }
        set { _LastName = value; }
    }

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }

    public bool IsActive
    {
        get { return _isActive; }
        set { _isActive = value; }
    }

    public class PersonFluentInterface
    {
        private readonly Person _person;

        public PersonFluentInterface(Person person)
        {
            _person = person;
        }

        public PersonFluentInterface FirstName(string firstName)
        {
            _person.FirstName = firstName;
            return this;
        }

        public PersonFluentInterface LastName(string lastName)
        {
            _person.LastName = lastName;
            return this;
        }

        public PersonFluentInterface Age(int age)
        {
            _person.Age = age;
            return this;
        }

        public PersonFluentInterface IsActive()
        {
            _person.IsActive = true;
            return this;
        }

        public PersonFluentInterface IsNotActive()
        {
            _person.IsActive = false;
            return this;
        }
    }
}

Now the code is clean, concise and quite readable.

Person person = new Person();
person.Set.FirstName("Pat").LastName("Frank").Age(30).IsActive();

 

Conclusion

 

This pattern for fluent interfaces is often seen in object configuration and setup.  It’s fairly easy to design and the objects configuration options are readily discoverable using intellisense.  As the complexity of an objects setup increased, a fluent interface becomes a more attractive option to ease the initialization burden.

 

 

kick it on DotNetKicks.com

3 Comments

  • Good post.
    The only thing missing is an implicit cast from PFI to Person, to write it like
    Person person = new Person().Set.FirstName("Pat").LastName("Frank").Age(30).IsActive();

    Also, personally, I find ‘With’ more readable than ‘Set’ for these cases.

    C# 3.0 object initializers will obsolete this usage, but until then it is quite cool.

  • Kalpesh says:

    Good post to introduce fluent interfaces.
    Isn’t this already present in c++ (remember cout << … << …)

    Also, VB has this already with..end with
    I also like what Andrey has to say abt c#3.0 thing

    Thanks.

  • Web Designer says:

    Nice post. My friend Adam told me about this blog a few weeks ago but this is the first time visiting. I’ll be back for sure.