Is it bad practice to make a setter return “this”?

2020-01-25 12:18发布

Is it a good or bad idea to make setters in java return "this"?

public Employee setName(String name){
   this.name = name;
   return this;
}

This pattern can be useful because then you can chain setters like this:

list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));

instead of this:

Employee e = new Employee();
e.setName("Jack Sparrow");
...and so on...
list.add(e);

...but it sort of goes against standard convention. I suppose it might be worthwhile just because it can make that setter do something else useful. I've seen this pattern used some places (e.g. JMock, JPA), but it seems uncommon, and only generally used for very well defined APIs where this pattern is used everywhere.

Update:

What I've described is obviously valid, but what I am really looking for is some thoughts on whether this is generally acceptable, and if there are any pitfalls or related best practices. I know about the Builder pattern but it is a little more involved then what I am describing - as Josh Bloch describes it there is an associated static Builder class for object creation.

27条回答
孤傲高冷的网名
2楼-- · 2020-01-25 12:51

It is better to use other language constructs if available. For example, in Kotlin, you would use with, apply, or let. If using this approach, you won't really need to return an instance from your setter.

This approach allows your client code to be:

  • Indifferent to the return type
  • Easier to maintain
  • Avoid compiler side effects

Here are some examples.

val employee = Employee().apply {
   name = "Jack Sparrow"
   id = 1
   foo = "bacon"
}


val employee = Employee()
with(employee) {
   name = "Jack Sparrow"
   id = 1
   foo = "bacon"
}


val employee = Employee()
employee.let {
   it.name = "Jack Sparrow"
   it.id = 1
   it.foo = "bacon"
}
查看更多
三岁会撩人
3楼-- · 2020-01-25 12:52

This scheme (pun intended), called a 'fluent interface', is becoming quite popular now. It's acceptable, but it's not really my cup of tea.

查看更多
何必那么认真
4楼-- · 2020-01-25 12:52

Because it doesn't return void, it's no longer a valid JavaBean property setter. That might matter if you're one of the seven people in the world using visual "Bean Builder" tools, or one of the 17 using JSP-bean-setProperty elements.

查看更多
ら.Afraid
5楼-- · 2020-01-25 12:53

Bad habit: a setter set a getter get

what about explicitly declaring a method, that does it for U

setPropertyFromParams(array $hashParamList) { ... }
查看更多
兄弟一词,经得起流年.
6楼-- · 2020-01-25 12:54

On first sight: "Ghastly!".

On further thought

list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));

is actually less error prone than

Employee anEmployee = new Employee();
anEmployee.setName("xxx");
...
list.add(anEmployee);

So quite interesting. Adding idea to toolbag ...

查看更多
beautiful°
7楼-- · 2020-01-25 12:55

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.

查看更多
登录 后发表回答