29

I frequently use a pattern where I using method chaining to setup an object, similar to a Builder or Prototype pattern, but not creating new objects with each method call, instead modifying the original object.

Example:

new Menu().withItem("Eggs").withItem("Hash Browns").withStyle("Diner");

Just wondering if there is a name for this pattern and whether it is considered an anti-pattern, because although it can read more fluently, it can lead to long method chains.

Martin Spamer
  • 542
  • 2
  • 13
Garrett Hall
  • 2,182
  • 1
  • 15
  • 16
  • 3
    A fluent interface is a matter of style. If you are writing an API provide alternative forms to it. – Oded Mar 02 '12 at 14:55
  • 1
    For more discussion, take a look at this question: http://programmers.stackexchange.com/questions/69519/c-when-to-go-fluent – Eric King Mar 02 '12 at 15:01
  • @Oded It is possible to use such an API without chaining by just making each call a separate statement, or did you have another idea for an alternative? – Garrett Hall Mar 02 '12 at 15:04
  • @GarrettHall - Of course it is possible, but then you end up calling things like `menu.withStyle("")` without context. You need _two_ APIs in such a case. – Oded Mar 02 '12 at 15:08
  • 2
    @GarrettHall The point of the 'fluent interface' *is* the method chain, which is meant to be read like a sentence. In this sense, the long method chain is not considered bad. But, and here I agree with Oded, it would be best to also provide the same functionality in a more conventional syntax. That way, the developer can choose which method to use. – Eric King Mar 02 '12 at 15:11
  • A great discussion on the subject can be heard on the HanselMinutes podcast at: http://www.hanselminutes.com/260/net-api-design-that-optimizes-for-programmer-joy-with-jonathan-carter – Eric King Mar 02 '12 at 15:12
  • I have a theory that if a person likes fluent interfaces, that they'll like functional programming. FI is semantically very similar to FP. – Steven Evers Mar 02 '12 at 16:26

3 Answers3

42

Fluent Interface

I've always heard of this method being called a 'fluent interface', as coined by Eric Evans (of Domain Driven Design fame) and Martin Fowler (of Agile Manifesto fame).

The main drawbacks are the readability (which some folks love and some hate), and the fact that it can be harder to debug in some cases because the entire chain of actions may be considered a single statement when stepping through it.

I certainly don't consider it an anti-pattern, although I've only used the technique a few times myself.

Eric King
  • 10,876
  • 3
  • 41
  • 55
  • 4
    Note that the proponents are pretty insistent that a fluent interface involves much more than just method chaining, although it is often unclear what else is meant by that term. – Kilian Foth Mar 02 '12 at 15:12
  • Is it common for the entire chain to be considered a single statement? That sounds like a poorly designed debugger issue to me. – blueberryfields Mar 02 '12 at 16:06
  • I've not come across a debugger that treats chains as a single statement, but it can still be a pain if you're only interested in one of the methods towards the end of the chain, in one particular chain. – vaughandroid Mar 02 '12 at 16:29
  • 1
    I work in C#, and the .NET debugger lets me step into the individual methods just fine. Other languages, I'm not so sure. – Eric King Mar 02 '12 at 17:02
  • 2
    @KilianFoth As noted in the question's comments, the chained methods in a fluent interface should be readable almost as a sentence. Sometimes this means that the individual methods should have different names than is otherwise considered good practice – Izkata Mar 02 '12 at 17:06
  • @ EricKing That's true, but as @vaughandroid notes, if you are interested in a method at the end, there is no way to step over one of the calls, nor set a breakpoint at the last method call so that the debugger stops right before the call you are interested in. – TamaMcGlinn Oct 29 '18 at 11:03
  • @TamaMcGlinn Yeah, definitely. I agree. That's why I listed debugging experience as one of the drawbacks to this style. – Eric King Oct 29 '18 at 16:46
  • Fluent interfaces is a sneak attack on closed source... with open source you just go to the source of the method you want and place a breakpoint inside it :D – Erk Jul 08 '19 at 02:01
6

Method chaining like that is usually called a Fluent Interface when there is some kind of flow or discoverability in the chain. Alternatively, you can think of an api like jQuery that relies heavily on method chaining as not 'fluent' because there's not the same emphasis on discoverability -- it's more for convenience.

For your example (using withx, withy) you can consider this a variant of the Builder pattern because you've got a specialized class that, given some state (method calls) knows how to return a properly configured object.

This isn't an anti-pattern if used appropriately.

pfries
  • 441
  • 3
  • 5
  • What is discoverabilty? The ability to find the methods you need through the API's autocomplete? – Josiah Yoder Feb 02 '18 at 18:58
  • I am not familiar with jQuery. How are their method chains only for convenience, not discoverability? Because there are so many ways to chain it is overwhelming even with autocomplete? – Josiah Yoder Feb 02 '18 at 19:00
3

whether it is considered an anti-pattern,

definitely not an anti-pattern. jQuery is probably the most well used implementation of this.

because although it can read more fluently, it can lead to long method chains

Yes it can, but what is the alternative ? You can end up with almost a plain english sentence, with the api guiding you to what is available and appropriate.

NimChimpsky
  • 4,627
  • 4
  • 26
  • 39
  • ..and you get what you want in 1 line, instead of 8 - 10. Which is good if you are only writing a one liner in a terminal. Easier to recall 1 command than 10. Because it is fluent and the methods have descriptive names it is also easier to read. Sadly a lot of this in Python2 can no longer be done in Python3/Python4. – mckenzm Oct 08 '18 at 21:57