我刚刚阅读了 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方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top