views:

611

answers:

10

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.

A: 

Seems that method chaining is at least one way to write smart code in java. Even if not every one agrees..

Mercer Traieste
+2  A: 

This seems kinda subjective.

Method chaining is not soemthing that is inherently bad or good imo.

Readability is the most important thing.

(Also consider that having large numbers of methods chained will make things very fragile if something changes)

John Nicholas
It might indeed be subjective, hence the subjective tag. What I hope the answers will highlight to me is in which cases method chaining would be a good idea - right now I don't see much any, but I think this is just my failure to understand the good points of the concept, rather than something inherently bad in the chaining itself.
Ilari Kajaste
Wouldn't it be inherently bad if it results in high coupling? Breaking the chain into individual statements does not lower readability.
aberrant80
depends on how dogmatic you want to be. If it results in something more readable then this could be preferable in a lot of situations.The big problem I have with this approach is that most methods on an object will return references to the object itself but often the method will return a reference to a child object upon which you can chain more methods. Once you start to do this then it becomes very difficult for another coder to disentangle what is going on.Also any change in functionality of a method is going to be a pain to debug in a large compound statement.
John Nicholas
+5  A: 

In my opinion, method chaining is a bit of a novelty. Sure, it looks cool but I don't see any real advantages in it.

How is:

someList.addObject("str1").addObject("str2").addObject("str3")

any better than:

someList.addObject("str1")
someList.addObject("str2")
someList.addObject("str3")

The exception might be when addObject() returns a new object, in which case the unchained code may be a little more cumbersome like:

someList = someList.addObject("str1")
someList = someList.addObject("str2")
someList = someList.addObject("str3")
Tom Dalling
It's more concise, as you avoid two of the 'someList' parts even in your first example and end up with one line instead of three. Now if that is actually good or bad depends on different things and perhaps is a matter of taste.
Fabian Steeg
The real advantage of having 'someList' only once, is that it's then much easier to give it a longer, more descriptive name. Any time a name needs to appear multiple times in quick succession, there's a tendency to make it short (to reduce repetition and improve readability), which makes it less descriptive, hurting readability.
Chris Dodd
+5  A: 

I agree that this is subjective. For the most part I avoid method chaining, but recently I also found a case where it was just the right thing - I had a method which accepted something like 10 parameters, and needed more, but for the most time you only had to specify a few. With overrides this became very cumbersome very fast. Instead I opted for the chaining approach:

MyObject.Start()
    .SpecifySomeParameter(asdasd)
    .SpecifySomeOtherParameter(asdasd)
    .Execute();

This is something like a factory pattern. The method chaining approach was optional, but it made writing code easier (especially with IntelliSense). Mind you that this is one isolated case though, and is not a general practice in my code.

The point is - in 99% cases you can probably do just as well or even better without method chaining. But there is the 1% where this is the best approach.

Vilx-
+4  A: 

Martin Fowler has a good discussion here:

Method Chaining

When to use it

Method Chaining can add a great deal to the readability of an internal DSL and as a result has become almost a synonum for internal DSLs in some minds. Method Chaining is best, however, when it's used in conjunction with other function combinations.

Method Chaining is particularly effective with grammars like parent::= (this | that)*. The use of different methods provides readable way of seeing which argument is coming next. Similarly optional arguments can be easily skipped over with Method Chaining. A list of mandatory clauses, such as parent::= first second doesn't work so well with the basic form, although it can be supported well by using progressive interfaces. Most of the time I'd prefer Nested Function for that case.

The biggest problem for Method Chaining is the finishing problem. While there are workarounds, usually if you run into this you're better off usng a Nested Function. Nested Function is also a better choice if you are getting into a mess with Context Variables.

0xA3
+2  A: 

It is dangerous because you may be depending on more objects than expected, like then your call returns an instance of another class:

I will give an example:

foodStore is an object that is composed of many food stores you own. foodstore.getLocalStore() returns an object that holds information on the closest store to the parameter. getPriceforProduct(anything) is a method of that object.

So when you call foodStore.getLocalStore(parameters).getPriceforProduct(anything)

you are depending not only on FoodStore as you though, but also on LocalStore.

Should getPriceforProduct(anything) ever changes, you need to change not only FoodStore but also the class that called the chained method.

You should always aim for loose coupling among classes.

That being said, i personally like to chain them when programming Ruby.

rprandi
+2  A: 

Many use method chaining as a form of convenience rather than having any readability concerns in mind. Method chaining is acceptable if it involves performing the same action on the same object - but only if it actually enhances readability, and not just for writing less code.

Unfortunately many use method chaining as per the examples given in the question. While they can still be made readable, they are unfortunately causing high coupling between multiple classes, so it's not desirable.

aberrant80
+1  A: 

Method chaining may simply be a novelty for most cases but I think it has it's place. One example might be found in CodeIgniter's Active Record use:

$this->db->select('something')->from('table')->where('id', $id);

That looks a lot cleaner (and makes more sense, in my opinion) than:

$this->db->select('something');
$this->db->from('table');
$this->db->where('id', $id);

It really is subjective; Everyone has their own opinion.

Nathan
+1  A: 

Personally, I prefer chaining methods that only act on the original object, e.g. setting multiple properties or calling utility-type methods.

foo.setHeight(100).setWidth(50).setColor('#ffffff');
foo.moveTo(100,100).highlight();

I do not use it when one or more of the chained methods would return any object other than foo in my example. While syntactically you can chain anything as long as you are using the correct API for that object in the chain, changing objects IMHO makes things less readable and can be really confusing if the APIs for the different objects have any similarities. If you do some really common method call at the end (toString(), print(), whatever) which object are you going to get? Someone casually reading the code might not catch that it would be some implicitly returned object in the chain rather than the original one.

Chaining different objects can also lead to unexpected null errors. In my examples, assuming that foo is valid, all the method calls are "safe" (e.g., valid for foo). In your example:

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

...there's no guarantee (as an outside developer looking at the code) that getSchedule will actually return a valid, non-null schedule object. Also, debugging this style of code is often a lot harder since many IDEs will not evaluate the method call at debug time as an object that you can inspect. IMO, anytime you might need an object to inspect for debugging purposes, I prefer to have it in an explicit variable.

bmoeskau
A: 

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.

RAY