15

在我工作的公司,有一份文档描述了我们应该在 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

4 回答 4

6

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

于 2013-04-17T12:47:58.893 回答
5

这种做法的唯一严肃基础是避免可变对象;关于它“令人困惑”并导致“期望失败”的批评相当微弱。一个人在没有首先熟悉它的语义之前永远不应该使用一个对象,并且仅仅为了迎合那些选择不阅读 Javadoc 的人而对 API 实施约束根本不是一个好习惯——尤其是因为,正如您所指出的,返回this以实现一个流畅的 API 设计是 Java 中的标准方法之一,并且确实是一种非常受欢迎的方法。

于 2013-04-17T12:56:41.960 回答
1

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

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

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

所以我在这里唯一能建议的就是和写这个文档的人谈谈 :)

希望这可以帮助

于 2013-04-17T12:56:22.140 回答
0

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

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

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

生成的代码大约是原来的 1/4 大小,并且更具可读性/可维护性,即使对于可能不熟悉使用 GridBagConstaints 的临时开发人员也是如此。

于 2013-04-17T14:42:20.533 回答