Before jumping to furious-coding-mode, we need to think about the problem in hand:
we have a bunch of methods that will allow us to write strings separated by some sort of token (being urls the subject being processed, the forward-slash “/” got the job). Those strings need to be non-empty and order matters.
This simple analysis tells us that we need to have some sort of context passed to each one of the implementations, and that context allows appending non-empty strings to a collection. When the user is done adding fragments to the url, that collection needs to be processes in order to be transformed into the string representing the url.
The first piece of the puzzle is a collection that allows appending non-empty members, entering the NonEmptySegmentCollection:
Very simple class, but allows having the logic to discard empty strings right where it belongs, in the container collection itself, and that is always a good place.
Inner closure implementation
Let’s start fleshing out the Write() method as it is the heart and soul of the closure ingredient. The idea is create the class that implements the “firestarter” of the api and pass the context. This context will be passed around for each one of the implementation classes, which will add the segments for the url and the context will be retrieved from the end implementation.
And the IEnd interface has to make available that context, so that it will be changed to:
Thinking a bit ahead, all the areas will be inheriting from a base class, making complying to the restriction to pass the context around easier and providing a shortcut to add segments to this context:
Foundations in place, the implementation of the different areas is a matter of pushing the right segments into the context and create the implementation of the interface:
And so on and so forth for the rest of the classes.
Well, almost… How do we know we have the same functionality as before?
Writing unit tests that exhibit the same behavior as the non-fluent counterpart is the answer:
We have included lots of code in this post, lots of code in the rest of the series. All of which can be accessed through Google Code.
We have proved that having APIs with high usability (and looking good to the developer’s eye) is not only feasible, but relatively easy with a bit of thinking.
Of course, they take effort to build instead of simpler APIs but the benefits are only harvested with the use, meaning: avoid implementing in areas of the code with low usage as costs will outrun benefits easily.
I hope you gained some knowledge with this series and had at least half of fun I had writing it.