Method chaining

Author: Kasper B. Graversen, 21/06/08
Keywords: Method chaining, Shortcut programming
Abstract: Method chaining enables terser and more natural interaction with objects. Despite it has been around in languages such as Smalltalk since the 1960's it has been "forgotten" in main stream languages such as Java, C# and Python.
subscribe to my RSS feed


Bookmark and Share


Method chaining

If you are unfamiliar with the term "method chaining" now is the time to pick up a good practice. The java bean paradigm<tm> dictates a style of programming where get() methods returns a given value of a type, and set() methods return void as shown below
class MyBean {
	String getAddress() { ... }
	void setName(String name) { ... }
	void setAddress(String adr) { ... }
	...
}
This leads to object interaction where the object to interact with always has to be named explicitly:
MyBean bean = new MyBean();
bean.setName("foo");
bean.setAddress("bar");

While this may seem to be perfectly ordinary code, it hinders a proper flow to have the exclamatory bean repeated again and again. It's just plain annoying! Why can't the programming language understand that I want to do more than one thing on the same object? Well, it can and. Let's see the transformation from clumsy to elegant.
HashMap map = new HashMap();
h.put("bar", 1);
foo(h);
and
Calendar c = Calendar.getInstance();
c.set(2007, 2, 28);
c.setMillis(0);
foo(c);
Explain to me why the factory methods for Calendar can't take as arguments the day you want to use? Any how, these code-snippets be expressed more elegantly simply as
foo( new HashMap().put("bar", 1) );
and
foo( Calendar.getInstance().set(2007, 2, 28).setMillis(0) );

Applying Method Chaining

In order to simplify repeated object interactions on the same object the old trick Method Chaining originating the world of Smalltalk should be enforced. The idea is to let methods return this rather than void, thus affecting especially set() and add() methods. Method chaining arose during the designers of Smalltalk persuit to minimize the number of keywords in the language, which lead to the discovery that void is an unnecesarry keyword!.

Applying the pattern to the above bean code yields:
MyBean bean = new MyBean()
.setName("foo")
.setAddress("bar);
or even
MyBean bean = new MyBean().setName("foo").setAddress("bar);
Where setAddress() is defined e.g. as void setAddress(String adr) { this.adr = adr; return this; } Similarly, for the other above problems, they can elegantly be solved using method chaining. Had Hashtabe.put() returned this, the following code would be legal
foo( new Hashtable().put("bar", 1) );

Where to apply?

Popular frameworks such as Hibernate project seems to be re-discovering this arcane style of coding, and it is also heavily used in the recent movement creating fluid interfaces. So when should you use method chaining? While not set in stone, as a rule of thumb all methods presently returning void are candidates for being changed into method chaining style. But as with everyhting in programming, use you head! If you find certain methods shouldn't be chainable, then keep the methods void. Do what you find natural. For simple CRUD webapps you probably won't be using the pattern a lot, but when you are doing some kind of framework and you want the interaction to be fluent or "natural" then it's a super duper pattern to apply. See for example, SQL Orm's query builder for an advanced application of method chaining.

Drawbacks

So are there any drawbacks. Well, a few, but nothing that should turn you completely off. Let's go through the list.
  • There is a bit more to cod, since set-methods now has to contain a return statement, and IDE's such as Eclipse still only supports generating simple set-methods returning void. So potentially, you need to revise code that would otherwise be automatically generated.
  • Many debuggers operate on a line basis rather than on pr. expression, hence when you have a really long chain, it may be hard to step through...
  • If you have a core of a framework, reading the API in Javadoc may be a bit hard at times. The problem is that you have tailored your framework to be used in combination with other enities, not to be read in isolation. This, however, is more a problem with fluint interfaces rather than method chaining.
  • The pattern doesn't lend itself well to older versions of Java (pre Java 5), due to the lack of support for covariant return types of methods. That is, an overridding method in a subclass may wish to return something of a more specialized type (itself, which is more specialized as it is aa sub type :-). In such cases, your code requires using casts which is far from nice, hence review those situations and don't apply the pattern if things become too ugly for your taste.

Going full circle

Interestingly, I've recently seen posts suggesting Java to support method chaining by getting rid of the void construct.

The Spiffy Framework

The open source Spiffy Framework http://spiffyframework.sourceforge.net/ has certain helper methods to ease the use of common frameworks. When creating ArrayList's consider using http://spiffyframework.sourceforge.net/javadoc/spiffy/core/util/CollectionHelper.html as it enables you to code
class C {
    ArrayList<String> excludedFiles = CollectionHelper.arrayList("index.xml", "index-all.xml", "menu.xml");
}

rather than the clumsy code
class C {
    public List<String> excludeDirNames = new ArrayList<String>();
    public C() {
      excludedFiles.add("index.xml");
      excludedFiles.add("index-all.xml");
      excludedFiles.add("menu.xml");
    }
}

Similarly for maps, see http://spiffyframework.sourceforge.net/javadoc/spiffy/core/util/HashMapBuilder.html Others, fortunately, share the same point of view



Comments

If you have any comments to this article, please drop me a mail at firstclassthoughts at gmail dot com please indicate if I can't publish whole or parts of your comment on the site.


If you like this site consider subscribing to my RSS feed or how about subscribing by Email.


Help spread the word

Share this post on your favorite social bookmarking sites:
If you enjoyed this article, found it thought provoking, educative or otherwise good, please link to this page from your page or social bookmarking page. If you have any texts you think are worth publishing on First Class Thoughts, don't hesitate to send me a mail! Quality always welcome.


Bookmark and Share


The most recent contributions
28/07/09 Magic in mathematics II Fun with the number cyclic numbers, and specifically with 142857 as it is the smallest of such numbers.
13/07/09 My top 8 time-saving Firefox shortcuts This article presents my favorite top 8 time-saving shortcuts in Firefox 3.0 and Firefox 3.5. Get to know these and you'll be saving a lot of time. They have been ordered by "the element of most surprise"
20/05/09 Board Game Jungle speed / Arriba Review of the cool game "Jungle Speed" aka. "Arriba".
16/05/09 Danish Twin words "Twin words" are words that not only have multiple meanings, they must be composed next to each other in meaningful sentences. This article explores the concept of twin words.
Nothing of interest? Try browsing the entire article archive...