Java 让二传手返回“这个”是不好的做法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1345001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it bad practice to make a setter return "this"?
提问by Ken Liu
Is it a good or bad idea to make setters in java return "this"?
让java中的setter返回“this”是好还是坏主意?
public Employee setName(String name){
this.name = name;
return this;
}
This pattern can be useful because then you can chain setters like this:
这个模式很有用,因为这样你就可以像这样链接 setter:
list.add(new Employee().setName("Hyman Sparrow").setId(1).setFoo("bacon!"));
instead of this:
而不是这个:
Employee e = new Employee();
e.setName("Hyman 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.
...但它有点违反标准约定。我想这可能是值得的,因为它可以让 setter 做一些其他有用的事情。我已经看到这种模式在一些地方使用过(例如 JMock、JPA),但它似乎并不常见,并且通常只用于定义非常明确的 API,这种模式无处不在。
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.
我所描述的显然是有效的,但我真正想要的是关于这是否普遍可以接受的一些想法,以及是否存在任何陷阱或相关的最佳实践。我知道 Builder 模式,但它比我所描述的要复杂一些 - 正如 Josh Bloch 描述的那样,有一个关联的静态 Builder 类用于创建对象。
采纳答案by Tom Clift
I don't think there's anything specifically wrong with it, it's just a matter of style. It's useful when:
我不认为它有什么特别的问题,这只是风格问题。在以下情况下很有用:
- You need to set many fields at once (including at construction)
- you know which fields you need to set at the time you're writing the code, and
- there are many different combinations for which fields you want to set.
- 您需要一次设置多个字段(包括在构造时)
- 您知道在编写代码时需要设置哪些字段,并且
- 您要设置的字段有许多不同的组合。
Alternatives to this method might be:
此方法的替代方法可能是:
- One mega constructor (downside: you might pass lots of nulls or default values, and it gets hard to know which value corresponds to what)
- Several overloaded constructors (downside: gets unwieldy once you have more than a few)
- Factory/static methods (downside: same as overloaded constructors - gets unwieldy once there is more than a few)
- 一个大型构造函数(缺点:您可能会传递大量空值或默认值,并且很难知道哪个值对应于什么)
- 几个重载的构造函数(缺点:一旦你有多个,就会变得笨拙)
- 工厂/静态方法(缺点:与重载构造函数相同 - 一旦有多个就会变得笨拙)
If you're only going to set a few properties at a time I'd say it's not worth returning 'this'. It certainly falls down if you later decide to return something else, like a status/success indicator/message.
如果您一次只设置几个属性,我会说不值得返回“this”。如果您稍后决定返回其他内容,例如状态/成功指示器/消息,它肯定会下降。
回答by Noon Silk
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.
这种称为“流畅界面”的方案(双关语)现在变得非常流行。这是可以接受的,但这不是我真正喜欢的那杯茶。
回答by cletus
It's not bad practice. It's an increasingly common practice. Most languages don't require you to deal with the returned object if you don't want to so it doesn't change "normal" setter usage syntax but allows you to chain setters together.
这不是坏习惯。这是一种越来越普遍的做法。如果您不想,大多数语言不需要您处理返回的对象,因此它不会更改“正常”setter 使用语法,但允许您将 setter 链接在一起。
This is commonly called a builder pattern or a fluent interface.
这通常称为构建器模式或流畅的界面。
It's also common in the Java API:
它在 Java API 中也很常见:
String s = new StringBuilder().append("testing ").append(1)
.append(" 2 ").append(3).toString();
回答by djna
On first sight: "Ghastly!".
乍一看:“可怕!”。
On further thought
进一步思考
list.add(new Employee().setName("Hyman 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 ...
所以很有趣。将想法添加到工具包...
回答by Marian
At least in theory, it can damage the optimization mechanisms of the JVM by setting false dependencies between calls.
至少在理论上,它可以通过在调用之间设置错误的依赖关系来破坏 JVM 的优化机制。
It is supposed to be syntactic sugar, but in fact can create side effects in the super-intelligent Java 43's virtual machine.
它应该是语法糖,但实际上可以在超智能 Java 43 的虚拟机中产生副作用。
That's why I vote no, don't use it.
这就是为什么我投反对票,不要使用它。
回答by Ken
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.
因为它不返回 void,所以它不再是有效的 JavaBean 属性设置器。如果您是世界上使用可视化“Bean Builder”工具的七个人之一,或者使用 JSP-bean-setProperty 元素的 17 个人之一,这可能很重要。
回答by Luke Quinane
If you don't want to return 'this'
from the setter but don't want to use the second option you can use the following syntax to set properties:
如果您不想'this'
从 setter返回但不想使用第二个选项,您可以使用以下语法来设置属性:
list.add(new Employee()
{{
setName("Hyman Sparrow");
setId(1);
setFoo("bacon!");
}});
As an aside I think its slightly cleaner in C#:
顺便说一句,我认为它在 C# 中稍微干净一点:
list.Add(new Employee() {
Name = "Hyman Sparrow",
Id = 1,
Foo = "bacon!"
});
回答by Narek
In general it's a good practice, but you may need for set-type functions use Boolean type to determine if operation was completed successfully or not, that is one way too. In general, there is no dogma to say that this is good or bed, it comes from the situation, of course.
通常这是一个很好的做法,但您可能需要 set-type 函数使用 Boolean 类型来确定操作是否成功完成,这也是一种方法。一般来说,没有教条说这是好还是床,当然是从情况来看的。
回答by Carson Myers
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:
我不懂 Java,但我已经用 C++ 完成了这项工作。其他人说它使行真的很长而且很难阅读,但我已经这样做了很多次:
list.add(new Employee()
.setName("Hyman Sparrow")
.setId(1)
.setFoo("bacon!"));
This is even better:
这更好:
list.add(
new Employee("Hyman 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.
至少,我认为。但是,如果您愿意,欢迎您对我投反对票并称我为糟糕的程序员。我不知道你是否被允许在 Java 中这样做。
回答by Madhu
From the statement
从声明
list.add(new Employee().setName("Hyman Sparrow").setId(1).setFoo("bacon!"));
i am seeing two things
我看到两件事
1) Meaningless statement. 2) Lack of readability.
1)无意义的陈述。2)缺乏可读性。