Is it a good or bad idea to make setters in java return \"this\"?
public Employee setName(String name){
this.name = name;
return this;
}
I don't think there's anything specifically wrong with it, it's just a matter of style. It's useful when:
Alternatives to this method might be:
If you're only going to set a few properties at a time I'd say it's not worth returning 'this'. It certainly falls down if you later decide to return something else, like a status/success indicator/message.
I don't know Java but I've done this in C++. Other people have said it makes the lines really long and really hard to read, but I've done it like this lots of times:
list.add(new Employee()
.setName("Jack Sparrow")
.setId(1)
.setFoo("bacon!"));
This is even better:
list.add(
new Employee("Jack Sparrow")
.Id(1)
.foo("bacon!"));
at least, I think. But you're welcome to downvote me and call me an awful programmer if you wish. And I don't know if you're allowed to even do this in Java.
I have been making my setters for quite a while and the only real issue is with libraries that stick with the strict getPropertyDescriptors to get the bean reader/writer bean accessors. In those cases, your java "bean" will not have the writters that you would expect.
For example, I have not tested it for sure, but I would not be surprised that Jackson won't recognizes those as setters when creating you java objects from json/maps. I hope I am wrong on this one (I will test it soon).
In fact, I am developing a lightweight SQL centric ORM and I have to add some code beyong getPropertyDescriptors to recognized setters that returns this.
I prefer using 'with' methods for this:
public String getFoo() { return foo; }
public void setFoo(String foo) { this.foo = foo; }
public Employee withFoo(String foo) {
setFoo(foo);
return this;
}
Thus:
list.add(new Employee().withName("Jack Sparrow")
.withId(1)
.withFoo("bacon!"));
Warning: this withX
syntax is commonly used to provide "setters" for immutable objects, so callers of these methods might reasonably expect them to create new objects rather than to mutate the existing instance. Maybe a more reasonable wording would be something like:
list.add(new Employee().chainsetName("Jack Sparrow")
.chainsetId(1)
.chainsetFoo("bacon!"));
With the chainsetXyz() naming convention virtually everyone should be happy.
This particular pattern is called Method Chaining. Wikipedia link, this has more explanation and examples of how it's done in various programming languages.
P.S: Just thought of leaving it here, since I was looking for the specific name.
To summarize:
A couple other points not mentioned:
This violates the principal that each function should do one (and only one) thing. You may or may not believe in this, but in Java I believe it works well.
IDEs aren't going to generate these for you (by default).
I finally, here's a real-world data point. I have had problems using a library built like this. Hibernate's query builder is an example of this in an existing library. Since Query's set* methods are returning queries, it's impossible to tell just by looking at the signature how to use it. For example:
Query setWhatever(String what);
It introduces an ambiguity: does the method modify the current object (your pattern) or, perhaps Query is really immutable (a very popular and valuable pattern), and the method is returning a new one. It just makes the library harder to use, and many programmers don't exploit this feature. If setters were setters, it would be clearer how to use it.