让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类。
是的,我认为这是个好主意。
如果我能补充点什么,关于这个问题:
class People
{
private String name;
public People setName(String name)
{
this.name = name;
return this;
}
}
class Friend extends People
{
private String nickName;
public Friend setNickName(String nickName)
{
this.nickName = nickName;
return this;
}
}
这是可行的:
new Friend().setNickName("Bart").setName("Barthelemy");
Eclipse将不接受这一点!:
new Friend().setName("Barthelemy").setNickName("Bart");
这是因为setName()返回People而不是Friend,并且没有PeoplesetNickName。
我们如何编写setter来返回SELF类而不是类名呢?
这样就可以了(如果SELF关键字存在的话)。这真的存在吗?
class People
{
private String name;
public SELF setName(String name)
{
this.name = name;
return this;
}
}
我更喜欢使用“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()命名约定,几乎每个人都应该满意。