When I was first exposed to the idea of fluent interfaces my response was… big flipping deal.
It wasn’t until I actively started using fluent interfaces in my code did I begin to see their power and elegance.
What is a fluent interface? Here is the obligatory link to wikipedia ;)
In simple terms, its returning a type instead of void in order to achieve method chaining.
The end goal of the method chaining is to provide a more readable interface and code.
First, does it break the Law of Demeter?
Law of Demeter doesn’t equal the number of periods. I am of the opinion fluent interfaces do not violate the Law of Demeter.
What is LoD? Another link to wiki and here is a link to a stack overflow on this very subject! :)
To me, Law of Demeter is about restricting communication between objects.
A common violation of LoD (imho) is the exposure of a list property on an object. I believe this serves as a good example of LoD as well as being an example on how to make a fluent interface. :)
A Person object has a name and a list of friends.
1 2 3 4 5 6 7 8 9 10 |
|
I could then add friends by…
1 2 3 4 |
|
Now this is pretty typical, so what’s the problem?
Well my code knows WAY too much about Person. I know it has a list of friends and if they change that list to say a dictionary, I am hosed.
Not only that, but poor Person class… people can add friends to his collection without him every knowing. What if some additional logic needs to be done when adding a friend?
What if the person wants to record the birth date of every friend so they can send out birthday cards? Person is SOL.
As for Law of Demeter, my code is using the Person object to communicate through to the List
Let’s change Person to eliminate this problem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Now the only way to add a friend is through Person. Yippie!
1 2 3 4 |
|
If I wanted to make this a fluent interface all I would need to do is instead of returning void, return the Person class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Now I can do the same logic like…
1 2 3 4 |
|
That is pretty cool, but fluent interfaces really shine with the builder pattern.
This time around I want to force construction of a person through a builder and have the builder use a fluent interface. Notice my Person’s constructor and fields are private. I embed the builder class within the Person class so the builder has access to the constructor and fields. In this manner only my builder class has access to constructing a person. My builder can now act as an anti-corruption layer for Person.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
Now to create Roger and his friends I do..
1 2 3 4 5 6 |
|
It’s a simple example but maybe it sparked some ideas on how to use fluent interfaces to chain methods and make your code more approachable to people without Computer Science degrees. :D