设计:Java 和在 setter 方法中返回自引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:47:45  来源:igfitidea点击:

Design: Java and returning self-reference in setter methods

java

提问by pek

For classes that have a long list of setters that are used frequently, I found this way very useful (although I have recently read about the Builder patternin Effective Javathat is kinda the same).

对于拥有一长串经常使用的 setter 的类,我发现这种方式非常有用(尽管我最近阅读了Effective Java中的Builder 模式,这有点相同)。

Basically, all setter methods return the object itself so then you can use code like this:

基本上,所有 setter 方法都返回对象本身,因此您可以使用如下代码:

myClass
    .setInt(1)
    .setString("test")
    .setBoolean(true);

Setters simply return this in the end:

Setter 最后简单地返回这个:

public MyClass setInt(int anInt) {
    // [snip]
    return this;
}

What is your opinion? What are the pros and cons? Does this have any impact on performance?

你有什么意见?优缺点都有什么?这对性能有什么影响吗?

Also referred to as the named parameter idiomin c++.

在 C++ 中也称为命名参数习惯用法

采纳答案by Bartosz Bierkowski

@pek
Chained invocation is one of proposals for Java 7. It says that if a method return type is void, it should implicitly return this. If you're interested in this topic, there is a bunch of links and a simple example on Alex Miller's Java 7 page.

@pek
链式调用是 Java 7 的提议之一。它表示,如果方法返回类型为 void,则应隐式返回this。如果您对这个主题感兴趣,Alex Miller 的 Java 7 页面上有一堆链接和一个简单示例。

回答by Blorgbeard is out

This is called a Fluent Interface, for reference.

这称为Fluent Interface,以供参考。

Personally, I think it's a pretty neat idea, but a matter of taste really. I think jQueryworks this way.

就个人而言,我认为这是一个非常好的主意,但确实是品味问题。我认为jQuery就是这样工作的。

回答by Bernard

I wouldn't do it myself, because to me it muddies what a particular method does, and the method-chaining is of limited use to me over doing it longhand. It isn't going to send me into a quivering ball of rage and psychosis, though, which is always a good thing. :')

我不会自己做,因为对我来说它混淆了特定方法的作用,并且方法链对我来说在手头上做的用途有限。不过,它不会让我陷入愤怒和精神病的颤抖中,这总是一件好事。:')

I wouldn't be concerned about performance; just ask Knuth.

我不会关心性能;问问 Knuth。

回答by Tom Hawtin - tackline

It makes sense for builders, where all you are going to do is set a load of stuff, create the real object and throw the builder away. For builders, you might as well get rid of the "set" part of the method name. Similarly, immutable types don't really need the "get".

这对于建造者来说是有意义的,您要做的就是设置一堆东西,创建真实的对象并将建造者扔掉。对于构建器,您不妨去掉方法名称的“set”部分。同样,不可变类型也不需要“get”。

Something thing = new SomethingBuilder()
    .aProperty(wotsit)
    .anotherProperty(somethingElse)
    .create();

A useful trick (if you don't mind a ~2K runtime overhead per class) is to use the double brace idiom:

一个有用的技巧(如果您不介意每个类的运行时开销约为 2K)是使用双括号习语:

JFrame frame = new JFrame("My frame") {{
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocation(frameTopLeft);
    add(createContents());
    pack();
    setVisible(true);
}};

回答by Cagatay

I find this to be in poor style when used in setters. Immutable classes are usually a better fit for chaining, such as:

我发现这在二传手中使用时风格不佳。不可变类通常更适合链接,例如:

aWithB = myObject.withA(someA).withB(someB);

where myObjectis of this class:

myObject这个班级在哪里:

class MyClass {
    withA(TypeA a) {
         this.a.equals(a) ? this : new MyClass(this, a);
    }

    private MyClass(MyClass copy, TypeA a) {
        this(copy);
        this.a = a;
    }
}

The builder pattern is also useful, since it allows the final object to be immutable while preventing the intermediate instances you would normally have to create when using this technique.

构建器模式也很有用,因为它允许最终对象是不可变的,同时防止使用此技术时通常必须创建的中间实例。

回答by Dan Blair

I use to be a fan of the Java (and worse C#) practice of making getters and setters (get set properties) throughout an object. This use to be what I considered object oriented, but really this leads us just to exposing the guts and implementation of the object and not really taking advantage of encapsulation. There are times you can't get away from this (OR/M comes to mind), but in general the object should be set up and then perform its function. My dream objects tend to have one or two constructors, and maybe a half dozen functions that do work.

我曾经是在整个对象中创建 getter 和 setter(获取 set 属性)的 Java(以及更糟糕的 C#)实践的粉丝。这曾经是我认为的面向对象,但实际上这导致我们只是暴露对象的内在和实现,而不是真正利用封装。有时您无法摆脱这一点(想到 OR/M),但通常应设置对象,然后执行其功能。我梦想中的对象往往有一个或两个构造函数,可能还有六个可以工作的函数。

The reason for this is that once I started developing API's there is a real need to keep things simple. You really only want to add as much complexity as is required to get the job done, and getters and setters, while simple in themselves, add complexity in heaps when added in mass. What happens when I load setters i na different order? Anythign different? Are you sure?

这样做的原因是,一旦我开始开发 API,就真的需要让事情变得简单。你真的只想增加完成工作所需的复杂性,getter 和 setter 虽然本身很简单,但在大量添加时会增加堆的复杂性。当我以不同的顺序加载 setter 时会发生什么?有什么不同吗?你确定吗?

回答by pek

@Dan again, for more complex situations (immutability comes in mind) the Builder Pattern is a great solution.

再次@Dan,对于更复杂的情况(考虑到不变性),Builder Pattern 是一个很好的解决方案。

Also, I agree with you mostly in getters. I believe what you are saying is to mostly follow the "Tell don't ask" paradigm and I greatly agree. But that is oriented mostly at getters.

另外,我在大多数情况下都同意你的吸气剂。我相信你所说的主要是遵循“告诉不要问”的范式,我非常同意。但这主要是针对吸气剂的。

Lastly, all of the above are for classes that have a great deal of attributes. I don't see a reason for any if you only have less than, say, 7.

最后,以上所有内容都适用于具有大量属性的类。如果您只有少于 7 个,我看不出任何理由。

回答by Tim Howland

I ended up doing this a lot when working with the Apache POI excel library; I ended up writing helper methods that chained so I could apply formatting, data types, internal cell data, formulas, and cell positioning.

在使用 Apache POI excel 库时,我最终做了很多事情;我最终编写了链接的辅助方法,以便我可以应用格式、数据类型、内部单元格数据、公式和单元格定位。

For stuff with lots of little tiny flyweight elements that need to have finicky little tweaks applied it works pretty well.

对于有很多微小的享元元素,需要应用一些挑剔的小调整的东西,它工作得很好。

回答by Sanjay Mishra

How To Use

如何使用

/**
 *
 * @author sanjay
 */
public class NewClass {
private int left ;
private int top;
public void set(int x,int y)
    {
    left=x;
    top=y;
}
public NewClass UP(int x)
    {
    top+=x;
    return this;
}
public NewClass DOWN(int x)
    {
    top-=x;
    return this;
}
public NewClass RIGHT(int x)
    {
    left+=x;
    return this;
}
public NewClass LEFT(int x)
    {
    left-=x;
    return this;
}
public void Display()
    {
    System.out.println("TOP:"+top);
    System.out.println("\nLEFT\n:"+left);
}
}
public static void main(String[] args) {
    // TODO code application logic here
    NewClass test = new NewClass();
    test.set(0,0);
    test.Display();
    test.UP(20).UP(45).DOWN(12).RIGHT(32).LEFT(20);
     test.Display();

回答by mmattax

This idea is seen a lot in c++, it allows operations to be cascaded...

这个想法在 c++ 中经常看到,它允许操作级联......

for example

例如

std::cout << "this" << "is" << "cascading" 

is where the stream method << returns an instance of itself (*this).

是流方法 << 返回其自身实例 (*this) 的地方。

see this: http://www.java2s.com/Tutorial/Cpp/0180__Class/Cascadingmemberfunctioncallswiththethispointer.htm

看到这个:http: //www.java2s.com/Tutorial/Cpp/0180__Class/Cascadingmemberfunctioncallswiththethispointer.htm