让setter返回“this”是不好的做法吗?
在java中使setter返回“this”是好的还是坏主意?
public Employee setName(String name){
this.name = name;
return this;
}
这种模式可能很有用,因为你可以像这样链接setter:
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);
......但这有违符合标准惯例。 我想这可能是值得的,只是因为它可以使制定者做其他有用的事情。 我已经看到这种模式使用了一些地方(例如JMock,JPA),但它似乎并不常见,并且通常只用于在任何地方都使用此模式的定义良好的API。
更新:
我所描述的显然是有效的,但我真正想要的是关于这是否普遍接受的一些想法,以及是否存在任何陷阱或相关的最佳实践。 我知道关于Builder模式,但是它涉及到了我所描述的内容 - 就像Josh Bloch描述的那样,它有一个关联的用于创建对象的静态生成器类。
我认为它没有什么特别的错,它只是一个风格问题。 在以下情况下有用:
这种方法的替代方案可能是:
如果你一次只设置一些属性,我会说它不值得返回'this'。 如果你以后决定退还其他东西,比如状态/成功指示器/消息,它肯定会下降。
这不是一个坏习惯。 这是一种日益普遍的做法。 大多数语言不要求你处理返回的对象,如果你不想这样做,它不会改变“普通”setter使用语法,但可以让你连接setter。
这通常称为构建器模式或流畅的接口。
在Java API中也很常见:
String s = new StringBuilder().append("testing ").append(1)
.append(" 2 ").append(3).toString();
总结:
其他几点没有提到:
这违反了每个函数应该做一个(而且只有一个)事情的原则。 你可能会也可能不会相信这一点,但在Java中我相信它运作良好。
IDE不会为您生成这些(默认情况下)。
最后,这是一个真实世界的数据点。 使用像这样构建的库,我遇到了问题。 Hibernate的查询生成器就是现有库中的一个例子。 由于Query的set *方法正在返回查询,因此仅通过查看签名如何使用它是不可能的。 例如:
Query setWhatever(String what);
它引入了一个不明确的地方:方法是修改当前对象(你的模式)还是Query可能是不可变的(一种非常流行和有价值的模式),并且方法返回一个新的。 这只会让图书馆更难使用,许多程序员不会利用这一功能。 如果安装者是安装者,那么如何使用安装者会更清楚。
上一篇: Is it bad practice to make a setter return "this"?
下一篇: Abstract Factory vs Factory method: Composition vs Inplement?