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)
DSL Fluent Interface Example: (Rhino Mocks)
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
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.
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).
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.
Now the code is clean, concise and quite readable.
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.