用Java链接的方法

时间:2012-07-19 13:22:51

标签: java methods chaining method-chaining

虽然我在前面回答了一些问题,但最近我一直在做的一些工作中,我一直在想为什么Java不支持对其内置类进行方法链接。

例如,如果我要创建一个Car类,我可以通过重新this而不是void来使其可链接,如下所示:

public class Car {
    private String make;        

    public Car setMake(String make) {
        this.make = make;
        return this;
    }   
}

为什么内置库不倾向于以这种方式做事有什么特别的原因?方法链是否存在缺点?

我可能忽略了一些可以解释缺少方法链接的东西,但是默认情况下返回void的任何setter方法都应该返回对 this 的引用(至少在我看来应该如此)。这将使以下情况变得更加清洁。

container.add((new JLabel("label text")).setMaximumSize(new Dimension(100,200)));

而不是更长的啰嗦:注意:如果你愿意,它不会阻止你以这种方式编码。

JLabel label = new JLabel("label text");
label.setMaximumSize(new Dimension(100,200));
container.add(label);

我很想知道这个决定背后的原因,如果我不得不猜测会有与此相关的开销,所以只应在需要时使用。

6 个答案:

答案 0 :(得分:33)

的Eh。可以在两个方向上进行可读性论证 - 这样的事情就是试图将过多的东西放在一行中。

但老实说,我怀疑这是出于历史原因:普遍的“链接”行为并没有真正变得流行或众所周知,例如Swing正在开发中。您可能会争辩说它应该在以后添加,但是这样的事情往往会产生二进制不兼容性以及Sun / Oracle历来非常谨慎的其他问题。

更新的JDK库 - 请参阅例如ByteBuffer对于一个主要的,众所周知的示例 - 提供了链接行为等,这是有意义的。

答案 1 :(得分:19)

我能想到的另一个原因是表现,或者更准确地说:不为你不能使用的东西买单。 return this在每个方法之后都不是很昂贵,但仍然需要很少的额外CPU周期和一个CPU注册表。

甚至有一个想法是为每个声明return this返回值的方法添加隐式void,但它被拒绝了。

答案 2 :(得分:9)

虽然我们可以猜测真正的原因,但其中一个可能是严格来说,它不是非常OO。

如果您将方法视为表示建模世界的操作的操作,则方法链不适合该图片。

另一个原因可能是当您尝试覆盖链式方法时可能发生的混乱。想象一下这种情况:

class Foo {
   Foo chainedMethod() {...}
}

class Bar extends Foo {
   Foo chainedMethod() {...} //had to return Foo for Java versions < 1.5
   void doStuff();
}

因此,当您尝试new Bar().chainedMethod().doStuff()时,它将无法编译。 ((Bar)new Bar().chainedMethod()).doStuff()看起来不太好,是吗:)。

答案 3 :(得分:4)

方法链通常与Builder模式一起使用,您可以在StringBuilder类中看到它。除此之外,方法链接可以使命令和创建分离不那么清晰,例如repaint()是否也应该是流畅界面的一部分?然后我可以:

container.add(label).repaint().setMaximumSize(new Dimension(100,200)));

突然,我的调用顺序变得很重要,可以隐藏在链接方法中。

答案 4 :(得分:1)

不实施方法链接的原因将是以下部分:

  • Method Chaining的最大问题是整理问题。 虽然有解决方法,但通常如果遇到这种情况你就是这样 最好使用嵌套函数。嵌套函数也更好 选择是否遇到了Context Variables。

  • 无法保证链外的对象实际上会返回有效的对象, 非null对象。此外,调试这种代码风格通常很多 更难,因为许多* IDE *不会在调试时评估方法调用 时间作为你可以检查的对象

  • 当你将例程调用到其他类时,它会让人感到困惑 当有很多时,将参数传递给其中一个链接方法 传递的参数主要是因为线条很长

  • 还存在一个性能问题,它会对内存起作用

答案 5 :(得分:1)

您真的在询问Law of Demeter

“只与你的直接朋友交谈”

请注意,上面的链接是一个很好的资源,但你可以花很长时间在那里,但没有得到你想要的答案! : - )