6

I was thinking about code structure, and thinking about setters. These used to be void methods, so why don't use some possible return value, to enable some new code structure?

My idea was to change all the properties setters from void to an instance reference, so we can do setters sequentially, or something else. Here is an example:

public class MyClass {
    private int foo;
    private String bar;

    public MyClass setFoo(int foo) {
        this.foo = foo;
        return this;
    }

    public MyClass setBar(String bar) {
        this.bar = bar;
        return this;
    }

}

Then in some other place in the code we could do:

...
MyClass myInstance = new MyClass();
myInstance.setFoo(auxFoo).setBar(auxBar);
...

This allow to set all of class properties in a single line, useful in transformation methods.

Or even:

...
return myInstance.setFoo(auxFoo);

This one was my goal, to be able for example to set an error property, while returning it. This can simplify a catch block, for instance.

EDIT: After some answers I need to add:

  • The question is just about setters (not about doing this in all methods), and not restricted to chaining, but to other usages like the return example.
  • Could the change from void to something else create any problem? JavaBeans Introspection, for instance.
  • Can you see any more advantage or disadvantage of doing this?

I was hoping to see some discussion.

gvlasov
  • 18,638
  • 21
  • 74
  • 110
lpinto.eu
  • 2,077
  • 4
  • 21
  • 45
  • 1
    you might want to change the title, as you are not returning a class reference, you are returning an object reference. a class reference would be if you were returning Class. – Lucas Oct 06 '11 at 10:57

5 Answers5

13

It's a common technique, known as Method Chaining. Hibernate uses it in its Criteria classes, and is present in other popular frameworks, such as Wicket.

Generally, you've got to be careful and apply it in those void methods that you're sure that will never need to return anything. And you shouldn't be using it in your Java Beans, as it has been already discussed in this question: Does Java bean's setter permit return this?.

See this related SO question for some tips and drawbacks that may be useful while using this pattern.

Community
  • 1
  • 1
Xavi López
  • 27,550
  • 11
  • 97
  • 161
6

This is quite common practice and definitely a pattern - not an anti-pattern. It is more commonly referred to as :

http://en.wikipedia.org/wiki/Fluent_interface

and

http://en.wikipedia.org/wiki/Method_chaining

Some excellent libraries make use of it : jQuery and joda-time.

You can also specify when the chain ends by using an end method that does not return anything, or does something else entirely - in the case of an inner static builder it calls a constructor.

For what its worth I really like it.

Community
  • 1
  • 1
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • 1
    Fluent Interfaces are [more than merely chaining methods](http://ayende.com/blog/2639/fluent-interfaces-method-chaining). – Xavi López Oct 06 '11 at 11:20
  • 1
    @XaviLópez have you read that link, it defines nothing, just literally says fluent interface is different to method chaining, with no further explanation. – NimChimpsky May 27 '15 at 08:04
  • Fair point. These other answers ([here](http://stackoverflow.com/a/17940086/851811) and [here](http://stackoverflow.com/a/293576/851811)) elaborate on the difference between both concepts. Nice to get feedback.... almost 4 years later! :) – Xavi López May 27 '15 at 08:42
3

I think this pattern has its uses, and there's nothing inherently wrong with it.

I personally use it from time to time. There are well-established libraries using it, e.g. Gson. Even though not strictly a setter, Java's StringBuilder.append() is not dissimilar in spirit.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
2

I would not recommend doing this as many things rely on a specific method signature for setters to allow Bean like functionality. I do not know for certain, but this may stop things like spring, or jsf, or other tech that assumes Bean-like setters.

Lucas
  • 14,227
  • 9
  • 74
  • 124
2

This falls under a series of well-known and recognized patterns.

The general idea of having methods return a reference to be able to call more methods is called Method Chaining.

A more specific example of this type of method chaining is when methods are used to set properties of an instance used as input to a function. This is popular in C++ and is called the Named Parameter Idiom.

Agentlien
  • 4,996
  • 1
  • 16
  • 27