归还这有什么问题?

时间:2013-04-17 12:39:37

标签: java oop this

在我工作的公司,有一份描述我们应该在Java中遵循的良好实践的文档。其中之一是避免返回this的方法,例如:

class Properties {

  public Properties add(String k, String v) {
   //store (k,v) somewhere
     return this;
  }

}

我会有这样一堂课,所以我可以写:

 properties.add("name", "john").add("role","swd"). ...

我已经多次见过这样的习语,比如StringBuilder,并没有发现任何问题。

他们的论证是:

  

...可能是同步问题的根源或对目标对象状态的失败预期。

我想不出这可能是真的情况,你们中有人能给我一个例子吗?

编辑该文档没有指明任何有关可变性的内容,因此我没有看到链接调用和执行操作之间的差异:

properties.add("name", "john");
properties.add("role", "swd");

我会尝试与发起人取得联系,但我想用我的枪加载,这就是为什么我发布了这个问题。

已解决:我与其中一位作者交谈,他的初衷显然是为了避免释放尚未准备好的对象,例如在Builder模式中,并解释说如果上下文切换在调用之间发生,对象可能处于无效状态。我认为这与返回this无关,因为你可以犯同样的错误购买逐个调用方法,并且更多地与正确地同步构建过程有关。他承认该文件可能更加明确,并将很快修改。胜利是我的/我们的!

4 个答案:

答案 0 :(得分:6)

我的猜测是他们反对可变状态(通常是正确的)。如果您没有设计返回this的流畅接口,而是返回具有更改状态的对象的新不可变实例,则可以避免同步问题或没有"failed expectations about the states of target objects"。这可能解释了他们的要求。

答案 1 :(得分:5)

这种做法唯一严肃的基础是避免可变对象;批评它“混乱”并导致“失败的期望”是相当薄弱的。一个人应该从不使用一个对象而不先熟悉它的语义,并强制执行A​​PI的约束只是为了迎合那些选择不读Javadoc的人根本不是一个好习惯 - 特别是因为,你注意到,返回this来实现流畅的API设计是Java中的标准方法之一,而且确实非常受欢迎。

答案 2 :(得分:1)

我认为有时这种方法非常有用,例如“构建器”模式。

我可以说,在我的组织中,这种事情是由声纳规则控制的,我们没有这样的规则。

另一个猜测是,项目可能是在现有代码库的基础上构建的,这是一种遗留限制。

所以我在这里建议的唯一一件事就是与撰写本文档的人交谈:)

希望这有帮助

答案 3 :(得分:0)

我认为在某些情况下使用该模式是完全可以接受的。

例如,作为一名Swing开发人员,我经常使用GridBagLayout来发挥它的优势和灵活性,但是任何曾经使用它的人(在犯罪GridBagConstraints中都是它的伙伴)知道它可能非常冗长且不易阅读。

我在网上看到的一个常见的解决方法(我使用的是)是GridBagConstraints(GBConstraints)的子类,它为每个不同的属性都有一个setter,每个setter返回这个。这允许开发人员根据需要链接不同的属性。

结果代码的大小约为1/4,而且对于可能不熟悉使用GridBagConstaints的临时开发人员而言,可读/可维护性更强。