让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类。
总结:
它被称为“流畅接口”或“方法链接”。
这不是“标准”Java,尽管你现在看到的越来越多(在jQuery中工作得很好)
它违反了JavaBean规范,因此它将与各种工具和库分开,特别是JSP构建器和Spring。
它可能会阻止JVM通常会做的一些优化
一些人认为它能清理代码,另一些人认为它“可怕”
还有一些没有提到的要点:
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.
总结:
它被称为“流畅接口”或“方法链接”。
这不是“标准”Java,尽管你现在看到的越来越多(在jQuery中工作得很好)
它违反了JavaBean规范,因此它将与各种工具和库分开,特别是JSP构建器和Spring。
它可能会阻止JVM通常会做的一些优化
一些人认为它能清理代码,另一些人认为它“可怕”
还有一些没有提到的要点:
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.
是的,我认为这是个好主意。
如果我能补充点什么,关于这个问题:
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;
}
}