Setters返回实例引用.图案还是反图案?

lpi*_*.eu 6 java design-patterns coding-style

我正在考虑代码结构,并思考setter.这些曾经是void方法,那么为什么不使用一些可能的返回值,来启用一些新的代码结构呢?

我的想法是将所有属性setter从void更改为实例引用,因此我们可以按顺序执行setter或其他操作.这是一个例子:

public class MyClass {
    private int foo;
    private String bar;

    public MyClass setFoo(int foo) {
        this.foo = foo;
        return this;
    }

    public MyClass setBar(String bar) {
        this.bar = bar;
        return this;
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在我们可以做的代码中的其他地方:

...
MyClass myInstance = new MyClass();
myInstance.setFoo(auxFoo).setBar(auxBar);
...
Run Code Online (Sandbox Code Playgroud)

这允许在一行中设置所有类属性,这在转换方法中很有用.

甚至:

...
return myInstance.setFoo(auxFoo);
Run Code Online (Sandbox Code Playgroud)

这个是我的目标,例如在返回时可以设置错误属性.例如,这可以简化捕获块.

编辑: 经过一些答案我需要补充:

  • 问题只是关于setter(不是关于在所有方法中执行此操作),并且不限于链接,而是限于其他用法,return例如示例.
  • 从void到其他东西的变化是否会产生任何问题?例如,JavaBeans内省.
  • 你能看到这样做的优势或劣势吗?

我希望看到一些讨论.

Xav*_*ica 12

这是一种常见的技术,称为方法链接.Hibernate在其Criteria类中使用它,并且存在于其他流行的框架中,例如Wicket.

一般来说,你必须小心并将它应用于那些void你确定永远不需要返回任何东西的方法.你不应该在你的Java Bean中使用它,因为在这个问题中已经讨论过了:Java bean的setter许可证是否会返回?.

请参阅此相关的SO问题,了解使用此模式时可能有用的一些提示和缺点.


Nim*_*sky 6

这是很常见的做法,绝对是一种模式 - 而不是反模式.它通常被称为:

http://en.wikipedia.org/wiki/Fluent_interface

http://en.wikipedia.org/wiki/Method_chaining

一些优秀的库使用它:jQuery和joda-time.

您还可以使用不返回任何内容的end方法指定链的结束时间,或者完全执行其他操作 - 在内部静态构建器的情况下,它会调用构造函数.

我非常喜欢它的价值.