Even if you’re still stuck using a non-dynamic language (Java, C#, etc), you can steal a trick or two from the other side. Command chaining is an easy practice that can really simplify your code.
It’s easy. Put return this; before the end of each method in your class. Just say no to void!
Of course, you wouldn’t do it on functions. They’re supposed to return data. But following this practice for ‘command’ methods makes perfect sense, and allows calling code to be much cleaner.
Compare:
Element para = new Element("p");
para.set("class","song");
para.append("Hello World");
para.appendTo(document);
to
new Element("p") .set("class","song") .append("Hello World") .appendTo(document);
or
new Element("p") .set("class","song")
.append("Hello World")
.appendTo(document);
#2 and #3 are far more readable. If you want to draw attention to the commands (say they aren’t transparently obvious, or need inline comments), #3 is a better choice. If you want to focus on the surrounding logic, #2 cuts line usage down tremendously.
Both remove repetition and reduce re-factoring costs. As a bonus, you don’t have to clutter the scope with another arbitrarily named variable; you’ve created and finished with the object all in one statement.
Like all coding practices, there is a short adjustment period while you get used to reading and writing this style; however, I’m confident you’ll find it much faster to read and write code without that superfluous, repetitive text. DRY.
Just say no to void. Be nice to your callers.
I hadn’t considered this, but it’s definately worth keeping in mind. It’ll make code cleaner, that’s for sure!
But if your object is bean-like then this approach will not work….since bean setters are meant to be void. But still a goo d way to make code compact
I’m not sure if i agree that the fragment #2 is more readable. I see that #2 is in some sense more logical appending several behaviors in one line, but i think #1 is more clean and, therefore, more pleasing.
[...] Command chaining « Reflections of a computer linguist It’s easy. Put return this; before the end of each method in your class. Just say no to void! Published in: [...]
I guess it depends upon the scale of the project. If your code is only 4 lines as above, it doesn’t matter – but if you are configuring hundreds of object properties, this can make the difference between readable and unreadable code.
It is a good rule to keep every logical ‘step’ in your program small enough to fit on one page – however, this becomes difficult when you have lots of property sets in the middle of a loop, for example.
Typically, setting properties on an object is what I consider ‘noise’ code – it contains no actual logic, which is what you are looking for when you read code.
I have actually seen code where it’s a one liner but it broken into lines.
Taking your examples, it would look like this:
new Element("p").set("class","song"). //Example comment!!
append("Hello World").
appendTo(document);
To me this is easier to read and to comment. Having code in one line is great if you want to compact your script, but not so great if you want to read it and understand if after a month or two of not touching it
[Editor's note: I updated the article to include his example.]
its builder design pattern
@raveman
I think this convention might be commonly used *with* the builder design pattern, but I don’t think it’s actually part of the pattern.
Good point, Antonio – I’ve added example #3 as another example of command chaining usage. I’ve used that formatting style a lot, but completely forgot to mention it in the blog.
Putting everything one one line is a trade-off which completely depends on the situation.
You have to ask yourself in each situation: what is more important? Seeing the surrounding picture, or drawing attention to the member calls? If the member calls are significant enough to warrant a comment (i.e., they’re not transparently obvious), then you definitely want to line-break. If they’re transparently obvious and don’t deserve any comments, well, they probably don’t deserve their own lines.
Thanks!