Java 7中的链式调用?
-
06-07-2019 - |
题
我刚刚阅读了 Java 7预览演示文稿(pdf) 链式调用上的幻灯片。以下是幻灯片中使用的示例:
// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();
// Construction with chained invocation
Drink margarita = new DrinkBuilder()
.add("tequila")
.add("orange liqueur")
.add("lime juice")
.withRocks()
.withSalt()
.drink();
我对此感到复杂。不应该将太多的方法调用链接到一个语句中。另一方面,编写 margarita.this()
和 margarita.that()
也不太方便。
现在,我将从Delphi世界来到Java。在Delphi中有 with
语言结构。这是少数人所珍惜和许多人的厌恶(或者是相反的方式?)。我发现 with
比链式调用的想法更优雅(我相信它是基于 void
方法返回对它被调用的对象的引用 - 并且这是我不喜欢的部分,因为 void
应该返回 nothing )。
我希望Java采用带语言功能的,因此示例代码可以像这样编写:
Drink margarita = null;
with (new DrinkBuilder()) {
add("tequila");
add("orange liqueur");
add("lime juice");
withRocks();
withSalt();
margarita = drink();
}
我是唯一一个更喜欢这种链式调用解决方案的人吗?其他人认为 with
可能是Java语言的有用扩展吗? (让我想起某人对“Java ++”的需求的问题......)
解决方案
with 语句可以使用带有初始化程序的匿名类在Java中进行翻译:
Drink margarita = new DrinkBuilder() {{
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
}}.drink();
此处详细记录了使用此习语的缺点。
链式调用是Method Chaining的别名。这是众所周知的习语,适用于任何版本的Java:
class Chained {
public Chained withFoo() {
// ...
return this;
}
public Chained withBar() {
// ...
return this;
}
}
JDK 7的提案是允许无效返回类型的链接方法:
class ChainedJava7 {
public void withFoo() {
// ...
}
public void withBar() {
// ...
}
}
其他提示
我非常喜欢和
该表单的语句,但我更喜欢它们的VB版本:
With testObject
.Height = 100
.Text = "Hello, World"
.ForeColor = System.Drawing.Color.Green
End With
由于 With
块中的每个属性仍然必须以。
开头,您知道您正在引用Object属性而不是,例如,局部变量,减少任何命名空间冲突。
如果我们举个例子:
with (new DrinkBuilder()) {
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
margarita = drink();
}
没有简单的方法可以判断 withSalt()
是 DrinkBuilder
的方法还是本地类中的方法。如果你只允许在带块的中使用
-ed对象的方法,那么我认为它们变得不那么有用了。
我不喜欢 with
;我更喜欢 Python with
statement 。我同意你的意见, void
应该是 void
。在您提供的示例中,如果一个人真的希望能够链接方法调用,那么他们应该只更改其方法的返回类型,以便它们可以链接。
也许对一个对象的许多调用是一些代码需要移动的标志?
Joshua Bloch在 Effective Java 第2项强烈建议使用当你有一个包含很多参数的构造函数时,它就是Builder。一个原因是可以编写它以保证构建的对象始终处于一致状态。它还避免了复杂的“伸缩构造器”。在构建对象的类中。还有一个是如果你想让构建的对象不可变(例如,为了线程安全),它就不能有setter方法。