Method chaining - why is it a good practice, or not?

Ilari Kajaste picture Ilari Kajaste · Jul 9, 2009 · Viewed 66.1k times · Source

Method chaining is the practice of object methods returning the object itself in order for the result to be called for another method. Like this:

participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()

This seems to be considered a good practice, since it produces readable code, or a "fluent interface". However, to me it instead seems to break the object calling notation implied by the object orientation itself - the resulting code does not represent performing actions to the result of a previous method, which is how object oriented code is generally expected to work:

participant.getSchedule('monday').saveTo('monnday.file')

This difference manages to create two different meanings for the dot-notation of "calling the resulting object": In the context of chaining, the above example would read as saving the participant object, even though the example is in fact intended to save the schedule object received by getSchedule.

I understand that the difference here is whether the called method should be expected to return something or not (in which case it would return the called object itself for chaining). But these two cases are not distinguishable from the notation itself, only from the semantics of the methods being called. When method chaining is not used, I can always know that a method call operates on something related to the result of the previous call - with chaining, this assumption breaks, and I have to semantically process the whole chain to understand what the actual object being called really is. For example:

participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))

There the last two method calls refer to the result of getSocialStream, whereas the ones before refer to the participant. Maybe it's bad practice to actually write chains where the context changes (is it?), but even then you'll have to constantly check whether dot-chains that look similar are in fact keep within the same context, or only work on the result.

To me it appears that while method chaining superficially does produce readable code, overloading the meaning of the dot-notation only results in more confusion. As I don't consider myself a programming guru, I assume the fault is mine. So: What am I missing? Do I understand method chaining somehow wrong? Are there some cases where method chaining is especially good, or some where it's especially bad?

Sidenote: I understand this question could be read as a statement of opinion masked as a question. It, however, isn't - I genuinely want to understand why chaining is considered good practice, and where do I go wrong in thinking it breaks the inherent object-oriented notation.

Answer

RAY picture RAY · Oct 28, 2010

Just my 2 cents;

Method chaining makes debugging tricky: - You can't put the breakpoint in a concise point so you can pause the program exactly where you want it - If one of these methods throws an exception, and you get a line number, you have no idea which method in the "chain" caused the problem.

I think it's generally good practice to always write very short and concise lines. Every line should just make one method call. Prefer more lines to longer lines.

EDIT: comment mentions that method chaining and line-breaking are separate. That is true. Depending on the debugger though, it may or may not be possible to place a break point in the middle of a statement. Even if you can, using separate lines with intermediate variables gives you a lot more flexibility and a whole bunch of values you can examine in the Watch window that helps the debugging process.