The term Fluent Interface was coined by Eric Evans and Martin Fowler in Fowler’s bliki as a proposal to build more readable code in an object oriented API. It can be used with any object oriented language but in this series of posts, I will use only C# samples.
It’s based on the method chaining technique where the return of a method is an object that allows the call of another method making the code look like this:
This post was motivated by the fact that I did not find any guide or help to build a coherent Fluent interface. It was just the opposite I found several different approaches. After some thought, I've decided to write this one. This is not a definitive guide nor a set of rules but just a proposal to a set of best practices that would help to write a good fluent interface.
Let’s start defining some terms and concepts that I will use in this series:
- Sentence: is the statement or sequence of methods that defines a operation. The above C# sample is a simple sentence.
- Subject: is the object being manipulated by the sentence.
- Sentence Starter: is the first element of a sentence. In C#, it can be:
- An object
- A method that returns a object or property, or
- A type with
static methods that returns an instance object
The choice of using one of the above depends on the scope you are.
- Term: is a method or property that can be called from the subject at some point in the sentence. Terms can be:
- A Verb: A term that does something to the subject (sets a property, changes a value or even changes the current subject of the sentence.
- A Constraint: A term that limits the list of terms available next by changing the subject of the sentence.
- A Constraint Verb: A verb that also works as a constraint.
- Sentence Finalizer: An element that does not allow the sentence to continue. Generally it is a method that returns a
In a very strict approach, every sentence should end with a finalizer, but in practice that not true and the sentence can end in any point that we are satisfied with the state of the subject.
Readable Code X Natural Language Utopia
The initial objective of Fluent Interface was to create a more readable code. But some developers raise the flag of making it to make the code as close as possible to natural language. I consider that overcoding. Take the sentence:
Make a car that is yellow and uses gasoline.
We can write is as:
Both approaches are valid. Both are easy to read, but I think the first one is harder to code. And this is a very simple sentence.
I think we always need to analyze the problem and the context extensively before coding a fluent interface identifying the possible subjects and verbs to avoid making it too complicated to code or too raw.
Chaining X Nesting
Since we are talking about methods, there is always the question about chaining or nesting then. Consider this:
Make a car that has an engine that consumes gasoline,
has electronic ignition and max RPM of 4500 and paint it as yellow.
We can write is as:
Again both approaches are valid and easy to read, but instead of only using the method chain, we use the nesting to clarify that at some point, we are talking about the
Engine instead of the
Car. By using this alternative, we avoid using two Verbs that change the subject (
SetCar) and even define a clear scope for the internal subject (the
These are the initial considerations I'd like to mention. In the next post, I will talk about some techniques to code each part of the sentence with some samples. I will talk about the use of
static methods, generics, delegates, builders, etc. I hope it helps.