ALLINSIGHT

Home of the AlmostImplementedException

Fluent Interface Pattern

Chris already discussed a few design pattern like the Null Object Pattern and the Singleton Pattern and today its my pleasure to introduce you to the Fluent Interface Pattern.
This pattern is known since 2005 and the founders are Eric Evans and Martin Fowler as you can read in his post and it’s very likely you already used it. Maybe with Linq in .Net or JBehave in Java.

Lets start, like always with a simple example to show you the difference between a normal and the Fluent Interface. Here are the two calls that do basically the same:

The first call uses 4 parameter in the constructor. The second use no parameter, but set every needed value with a different statement. Each statement return its own instance in order to allow a chaining of the calls.
The main reason to use such a pattern is the benefit of readability. Especially when you have a complex api with multiple optional parameter its very cumbersome to find the right constructor or set all the needed parameter.
In the chaining above I use different words for the methods like “with” and “and” to illustrate the different meanings.
Before we starts with the problems of this approach have a look at the implementation of the Fluent Interface

The first code-block is the fluent interface. As you can see, you have to implement every method like a setter and return the own instance. If you want to do something else then setting something, then just do it :-).
The second example is a simple constructor which produces the same result.

At this point most of the examples ends and actually right here all the problems start.
How does an user know which of the parameter are mandatory? What if you have to choice between 2 parameter, because you can only set one of them? How do your api know its ready to work?
With the example above there is no way to solve those problems and the usage of constructor-parameter for the mandatory fields and fluent-methods for optionals like some examples show, isn’t even a pattern.

But don’t give up, there is a way and you will not like it (I sure don’t). You have to use interfaces. A lot of them.
Since we have 3 mandatory functions and one optional (andStopOnError) we’ll need 4 interfaces for our chain. Every method returns another one. Oh and by the way, you can’t use a constructor any more. You’ll need a static method which returns the first interface instead.
I extend the example above with a choice between a FileParser and a XmlParser and add a executor method.
First we’ll have to the define the interface-chain.

The interface-chain starts with IParser which is our entry-point. Our static method will return this one and you’re only allowed to execute withKeywords. Afterwards you can choice between withFileParser and withXmlParser. But only one of them can be execute in the chain since you’ll get the third interface as return. Then you can call withErrorHandler and the initialization process is finished.
Now you can choice between an execute which will end the chain or an optional parameter stopOnError.

And here is the implementation. Don’t forget to implement each interface and return the right one in every method.

Isn’t this nice? Now you can call this api without even knowing anything about it. A sample call is shown at the end of this post.

As you may have noticed you have a lot of work to implement a fluent interface. And its even worse when you have to change it afterwards.
You need a lot of interfaces too. Finding bugs is horrible since normally a callstack is line based and the whole call is a single line.
Another setback is the problem of misusage. What if someone put the result of withKeywords (in interface IParser2) into a variable and calls both functions (withFileParser and withXmlParser)? You have to handle such things, something you don’t have to do when you use multiple constructors.

Conclusion:
In my opinion fluent interfaces are a nice way to waste a lot of time and impress other developers, but you can’t use them with to many parameter or if the interface isn’t final.
On the plus side, you have an interface which practically is its own documentation and is easier to read for non-developers.

Share :

Leave a Reply

Your email address will not be published. Required fields are marked *