简体   繁体   English

归还这有什么问题?

[英]What's wrong with returning this?

At the company I work for there's a document describing good practices that we should adhere to in Java. 在我工作的公司,有一份文档描述了我们应该在Java中遵循的良好实践。 One of them is to avoid methods that return this , like for example in: 其中之一是避免返回this方法,例如:

class Properties {

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

}

I would have such a class so that I'm able to write: 我会有这样一堂课,所以我能写:

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

I've seen such idiom many times, like in StringBuilder and don't find anything wrong with it. 我已经多次看过这样的习惯用法,就像在StringBuilder一样,并没有发现它有任何问题。

Their argumentation is : 他们的论证是:

... can be the source of synchronization problems or failed expectations about the states of target objects. ...可能是同步问题的根源或对目标对象状态的失败预期。

I can't think of a situation where this could be true, can any of you give me an example? 我想不出这可能是真的情况,你们有谁能举个例子吗?

EDIT The document doesn't specify anything about mutability, so I don't see the diference between chaining the calls and doing: 编辑该文档没有指定任何有关可变性的内容,因此我没有看到链接调用和执行以下操作之间的差异:

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

I'll try to get in touch with the originators, but I wanted to do it with my guns loaded, thats' why I posted the question. 我会尝试与发起人联系,但我想用我的枪加载,这就是为什么我发布了这个问题。

SOLVED : I got to talk with one of the authors, his original intention was apparently to avoid releasing objects that are not yet ready, like in a Builder pattern, and explained that if a context switch happens between calls, the object could be in an invalid state. 解决 :我得与其中一位作者交谈,他的初衷显然是为了避免释放尚未准备好的对象,比如在Builder模式中,并解释说如果在调用之间发生上下文切换,则对象可能在无效的状态。 I argued that this had nothing to do with returning this since you could make the same mistake buy calling the methods one by one and had more to do with synchronizing the building process properly. 我认为这与返回this无关,因为你可能会犯同样的错误,一个接一个地调用方法,并且更多地与正确地同步构建过程有关。 He admitted the document could be more explicit and will revise it soon. 他承认该文件可能更加明确,并将很快修改。 Victory is mine/ours! 胜利是我的/我们的!

My guess is that they are against mutable state (and often are rightly so). 我的猜测是他们反对可变状态(通常是正确的)。 If you are not designing fluent interfaces returning this but rather return a new immutable instance of the object with the changed state, you can avoid synchronization problems or have no "failed expectations about the states of target objects" . 如果您没有设计返回this流程的fluent接口,而是返回具有已更改状态的对象的新不可变实例,则可以避免同步问题或者没有"failed expectations about the states of target objects" This might explain their requirement. 这可能解释了他们的要求。

The only serious basis for the practice is avoiding mutable objects; 这种做法唯一严肃的基础是避免可变对象; the criticism that it is "confusing" and leads to "failed expectations" is quite weak. 批评它“混乱”并导致“失败的期望”是相当薄弱的。 One should never use an object without first getting familiar with its semantics, and enforcing constraints on the API just to cater for those who opt out of reading Javadoc is not a good practice at all— especially because, as you note, returning this to achieve a fluent API design is one of the standard approaches in Java, and indeed a very welcome one. 一个人不应该在没有熟悉其语义的情况下使用对象,并且只是为了满足那些选择不读Javadoc的人而强制执行A​​PI的约束根本不是一个好习惯 - 特别是因为,正如你所注意到的,返回this以实现流畅的API设计是Java中的标准方法之一,实际上是一个非常受欢迎的方法。

I think sometimes this approach can be really useful, for example in 'builder' pattern. 我认为有时这种方法非常有用,例如在'builder'模式中。

I can say that in my organization this kind of things is controlled by Sonar rules, and we don't have such a rule. 我可以说,在我的组织中,这种事情是由声纳规则控制的,我们没有这样的规则。

Another guess is that maybe the project was built on top of existing codebase and this is kind of legacy restriction. 另一个猜测是,项目可能是在现有代码库的基础上构建的,这是一种遗留限制。

So the only thing I can suggest here is to talk to the people who wrote this doc :) 所以我在这里建议的唯一一件事就是和写这篇文章的人交谈:)

Hope this helps 希望这可以帮助

I think it's perfectly acceptable to use that pattern in some situations. 我认为在某些情况下使用该模式是完全可以接受的。

For example, as a Swing developer, I use GridBagLayout fairly frequently for its strengths and flexibility, but anyone who's ever used it (with it's partener in crime GridBagConstraints) knows that it can be quite verbose and not very readable. 例如,作为Swing开发人员,我经常使用GridBagLayout来发挥它的优势和灵活性,但任何曾经使用它的人(在犯罪GridBagConstraints中都是它的伙伴)都知道它可能非常冗长且不易阅读。

A common workaround that I've seen online (and one that I use) is to subclass GridBagConstraints (GBConstraints) that has a setter for each different property, and each setter returns this. 我在网上看到的一个常见的解决方法(我使用的是)是GridBagConstraints(GBConstraints)的子类,它为每个不同的属性都有一个setter,每个setter返回它。 This allows for the developer to chain the different properties on an as-needed basis. 这允许开发人员根据需要链接不同的属性。

The resultant code is about 1/4 the size, and far more readable/maintainable, even to the casual developer who might not be familiar with using GridBagConstaints. 生成的代码大小约为1/4,并且对于可能不熟悉使用GridBagConstaints的临时开发人员来说,可读/可维护性更强。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM