Creating API that is fluent

Solution 1:

This article explains it much better than I ever could.

EDIT, can't squeeze this in a comment...

There are two sides to interfaces, the implementation and the usage. There's more work to be done on the creation side, I agree with that, however the main benefits can be found on the usage side of things. Indeed, for me the main advantage of fluent interfaces is a more natural, easier to remember and use and why not, more aesthetically pleasing API. And just maybe, the effort of having to squeeze an API in a fluent form may lead to better thought out API?

As Martin Fowler says in the original article about fluent interfaces:

Probably the most important thing to notice about this style is that the intent is to do something along the lines of an internal DomainSpecificLanguage. Indeed this is why we chose the term 'fluent' to describe it, in many ways the two terms are synonyms. The API is primarily designed to be readable and to flow. The price of this fluency is more effort, both in thinking and in the API construction itself. The simple API of constructor, setter, and addition methods is much easier to write. Coming up with a nice fluent API requires a good bit of thought.

As in most cases API's are created once and used over and over again, the extra effort may be worth it.

And verbose? I'm all for verbosity if it serves the readability of a program.

Solution 2:

MrBlah,

Though you can write extension methods to write a fluent interface, a better approach is using the builder pattern. I'm in the same boat as you and I'm trying to figure out a few advanced features of fluent interfaces.

Below you'll see some sample code that I created in another thread

public class Coffee
{
    private bool _cream;
    private int _ounces;

    public static Coffee Make { get { return new Coffee(); } }

    public Coffee WithCream()
    {
        _cream = true;
        return this;
    }
    public Coffee WithOuncesToServe(int ounces)
    {
        _ounces = ounces;
        return this;
    }
}

var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);

Solution 3:

While many people cite Martin Fowler as being a prominent exponent in the fluent API discussion, his early design claims actually evolve around a fluent builder pattern or method chaining. Fluent APIs can be further evolved into actual internal domain-specific languages. An article that explains how a BNF notation of a grammar can be manually transformed into a "fluent API" can be seen here:

http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/

It transforms this grammar:

enter image description here

Into this Java API:

// Initial interface, entry point of the DSL
interface Start {
  End singleWord();
  End parameterisedWord(String parameter);
  Intermediate1 word1();
  Intermediate2 word2();
  Intermediate3 word3();
}

// Terminating interface, might also contain methods like execute();
interface End {
  void end();
}

// Intermediate DSL "step" extending the interface that is returned
// by optionalWord(), to make that method "optional"
interface Intermediate1 extends End {
  End optionalWord();
}

// Intermediate DSL "step" providing several choices (similar to Start)
interface Intermediate2 {
  End wordChoiceA();
  End wordChoiceB();
}

// Intermediate interface returning itself on word3(), in order to allow
// for repetitions. Repetitions can be ended any time because this 
// interface extends End
interface Intermediate3 extends End {
  Intermediate3 word3();
}

Java and C# being somewhat similar, the example certainly translates to your use-case as well. The above technique has been heavily used in jOOQ, a fluent API / internal domain-specific language modelling the SQL language in Java