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

时间:2008-08-28 03:03:53

标签: java

对于那些经常使用的一长串setter的类,我发现这种方式非常有用(尽管我最近读过有关 Effective Java 中的Builder pattern相同)。

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

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

Setters最后只是将其返回:

public MyClass setInt(int anInt) {
    // [snip]
    return this;
}
你有什么看法?优缺点都有什么?这对性能有影响吗?

在c ++中也称为named parameter idiom

11 个答案:

答案 0 :(得分:15)

@pek
链式调用是Java 7的提议之一。它表示如果方法返回类型为void,则应隐式返回 this 。如果您对此主题感兴趣,请在Alex Miller's Java 7 page上添加一些链接和一个简单示例。

答案 1 :(得分:10)

这称为Fluent Interface,仅供参考。

就个人而言,我认为这是一个非常巧妙的想法,但真的是品味问题。我认为jQuery就是这样的。

答案 2 :(得分:2)

我不会自己这样做,因为对我而言,特定方法所做的事情很混乱,并且方法链对我来说只是用来限制它。然而,这并不会让我陷入愤怒和精神病的颤抖之中,这总是一件好事。 :')

我不会担心表现;请问Knuth。

答案 3 :(得分:2)

对于构建者来说这是有意义的,你要做的就是设置一堆东西,创建真实的对象并抛弃构建器。对于构建器,您也可以去掉方法名称的“set”部分。同样,不可变类型实际上并不需要“获取”。

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

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

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

答案 4 :(得分:1)

我发现这在用于制表者时风格很差。不可变类通常更适合链接,例如:

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

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;
    }
}

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

答案 5 :(得分:0)

这个想法在c ++中看得很多,它允许操作级联......

例如


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

是流方法&lt;&lt;返回自身的实例(* this)。

请参阅:http://www.java2s.com/Tutorial/Cpp/0180__Class/Cascadingmemberfunctioncallswiththethispointer.htm

答案 6 :(得分:0)

我习惯于成为Java(以及更糟糕的C#)在整个对象中制作getter和setter(获取set属性)的实践。这个用法是我认为面向对象的,但实际上这导致我们暴露了对象的内核和实现而没有真正利用封装。有些时候你无法摆脱这种情况(OR / M浮现在脑海中),但一般来说,应该设置对象然后执行其功能。我的梦想对象往往有一两个构造函数,也许有六个函数可以工作。

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

答案 7 :(得分:0)

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

另外,我同意你的看法。我相信你所说的主要是遵循“Tell don't ask”范式,我非常同意。但这主要是针对吸气剂。

最后,以上所有内容都适用于具有大量属性的类。如果你的价格低于7,那我就没有理由说明。

答案 8 :(得分:0)

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

对于有很多微小的轻量级元素需要进行挑剔的小调整的东西,效果非常好。

答案 9 :(得分:0)

如何使用

/**
 *
 * @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();

答案 10 :(得分:-2)

我同意@Bernard这样的链接方法会影响制定者的目的。相反,我建议如果你总是创建这样的setter链,你可以为你的类创建一个自定义的构造函数,而不是

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

你做

new MyClass(1,"test",true);

这使它更具可读性,如果您选择使用它,可以使用它来使您的类不可变。