Posts tagged ‘method chaining’

Fluent Chaining

2013-06-30 14:24

Look at the following piece of jQuery code:

  1. $('span')
  2.     .attr('data-type', 'info')
  3.     .addClass('message')
  4.     .css('width', '100%')
  5.     .text("Hello world!")
  6.     .appendTo($('body'))
  7. ;

Of the two patterns it demonstrates, one is almost decisively bad: you shouldn’t build up DOM nodes this way. To get more concise and maintainable code, it’s better to use one of the client-side templating engines.

The second pattern, however, is hugely interesting. Most often called method chaining, it also goes by a more glamorous name of fluent interface. As you can see by a careful look at the code sample above, the idea is pretty simple:

Whenever a method is mostly mutating object’s state, it should return the object itself.

Prime example of methods that do that are setters: simple function whose pretty much only purpose is to alter the value of some property stored as a field inside the object. When augmented with support for chaining, they start to work very pleasantly with few other common patterns, such as builders in Java.
Here’s, for example, a piece of code constructing a Protocol Buffer message that doesn’t use its Builder‘s fluent interface:

  1. Person.Builder builder = Person.newBuilder();
  2. builder.setId(42);
  3. builder.setFirstName("John");
  4. builder.setLastName("Doe");
  5. builder.setEmail("johndoe@example.com")
  6. Person person = builder.build();

And here’s the equivalent that takes advantage of method chaining:

  1. Person person = Person.newBuilder()
  2.     .setId(42)
  3.     .setFirstName("John")
  4.     .setLastName("Doe")
  5.     .setEmail("johndoe@example.com")
  6.     .build();

It may not be shorter by pure line count, but it’s definitely easier on the eyes without all these repetitions of (completely unnecessary) builder variable. We could even say that the whole Builder pattern is almost completely hidden thanks to method chaining. And undoubtedly, this a very good thing, as that pattern is just a compensation for the deficiencies of Java programming language.

By now you’ve probably figured out how to implement method chaining. In derivatives of C language, that amounts to having a return this; statement at the end of method’s body:

  1. jQuery.fn.extend({
  2.     addClass: function( value ) {
  3.         // ... lots of jQuery code ...
  4.         return this;
  5.     },
  6.     // ... other methods ...
  7. });

and possibly changing the return type from void to the class itself, a pointer to it, or reference:

  1. public Builder setFirstName(String value) {
  2.     firstName_ = value;
  3.     return this;
  4. }

It’s true that it may slightly obscure the implementation of fluent class for people unfamiliar with the pattern. But this cost comes with a great benefit of making the usage clearer – which is almost always much more important.

Plus, if you are lucky to program in Python instead, you may just roll out a decorator ;-)

Tags: , , , , , ,
Author: Xion, posted under Programming » Comments Off on Fluent Chaining
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.