让java中的setter返回“this”是好还是坏?

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

这个模式很有用,因为你可以像这样设置链:

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

而不是这样:

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

...但这有点违背标准惯例。我认为这是值得的因为它可以让setter做一些其他有用的事情。我曾在一些地方看到过这种模式(例如JMock、JPA),但它似乎并不常见,而且通常只用于定义良好的api,在这些api中这种模式随处可见。

更新:

我所描述的显然是有效的,但我真正想要的是一些关于这是否被普遍接受的想法,以及是否存在任何陷阱或相关的最佳实践。我知道Builder模式,但它比我所描述的要复杂一些——正如Josh Bloch所描述的,有一个用于对象创建的相关静态Builder类。


当前回答

这可能可读性较差

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

或者这个

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

这比:

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

其他回答

我不懂Java,但我用c++做过。 也有人说这会让文字变得很长,很难读懂, 但我这样做过很多次:

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

这个更好:

list.add(
    new Employee("Jack Sparrow")
    .Id(1)
    .foo("bacon!"));

至少我是这么认为的。但如果你愿意,欢迎你给我投反对票,称我为糟糕的程序员。我不知道Java中是否允许这样做。

我更喜欢使用“with”方法:

public String getFoo() { return foo; }
public void setFoo(String foo) { this.foo = foo; }
public Employee withFoo(String foo) {
  setFoo(foo);
  return this;
}

因此:

list.add(new Employee().withName("Jack Sparrow")
                       .withId(1)
                       .withFoo("bacon!"));

警告:此withX语法通常用于为不可变对象提供“setter”,因此这些方法的调用者可能合理地期望它们创建新对象,而不是改变现有实例。也许更合理的措辞应该是:

list.add(new Employee().chainsetName("Jack Sparrow")
                       .chainsetId(1)
                       .chainsetFoo("bacon!"));

使用chainsetXyz()命名约定,几乎每个人都应该满意。

很久以前的答案,但我的两分钱…这是很好的。我希望这个流畅的界面被更多地使用。

重复'factory'变量不会在下面添加更多信息:

ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Foo.class);
factory.setFilter(new MethodFilter() { ...

恕我直言,这个更干净:

ProxyFactory factory = new ProxyFactory()
.setSuperclass(Properties.class);
.setFilter(new MethodFilter() { ...

当然,正如前面提到的答案之一,Java API必须进行调整,以便在某些情况下(如继承和工具)正确执行此操作。

坏习惯: setter集 getter get

如果显式地声明一个方法,为U

setPropertyFromParams(array $hashParamList) { ... }

如果我正在编写一个API,我使用“return this”来设置只会设置一次的值。如果我有任何其他值,用户应该能够改变,我使用标准的void setter代替。

然而,在我看来,这真的是一个偏好问题,链式设置器看起来确实很酷。