【问题标题】:Setter conventions in Java (return void or this)Java 中的 Setter 约定(返回 void 或 this)
【发布时间】:2015-04-25 18:22:35
【问题描述】:

我已经编写 Java 快一年了,我已经看到了 2 种不同的约定来说明人们如何实现他们的 setter。

为了说明这一点,以下是两种约定的示例。 (我也很想知道这两种模式的简明名称)

使用第一个约定的类,从它们的“设置”方法中不返回任何内容。像这样:

public class Classic{
    private double _x;
    private double _y;
    public Classic(){
        x = 0;
        y = 0;
    }
    public void setX(double d){//or boolean with a type check on input
        x = d;
    }
    public void sety(double d){
        y = d;
    }
}

使用替代约定的类从它们的 setter 方法返回自身。像这样:

public class Alternative{
    private double _x;
    private double _y;
    public Alternative(){
        x = 0;
        y = 0;
    }
    public Alternative setX(double d){
        x = d;
        return(this);
    }
    public Alternative sety(double d){
        y = d;
        return(this);
    }
}

不同之处在于使用替代方法语法,例如

Alternative NewAlt(double x,double y){
     return(new Alternative()
                .setX(x)
                .setY(y));
}

有可能而使用经典设置,相同的工厂方法会 看起来像这样。

Classic NewAlt(double x,double y){
     Classic temp = new Classic();
     temp.setX(x);
     temp.setY(x);
     return(temp);
}

其中哪一个更具可读性/可用性值得商榷。

我的问题是关于这两种模式之间的性能差异。它存在吗?如果是这样,差异有多大,它来自哪里?

如果没有性能差异,哪一个被认为是“更好的实践”?

【问题讨论】:

  • Java 中没有“自我”。
  • @AniketThakur 确定吗?如果没有使用构建器,为什么这种情况称为Builder pattern?据我所知,它“只是”"Fluent API"。
  • @kpie 当您将问题标记为 Java 时,请确保它使用标准 Java 编译器进行编译。你在这里已经有一段时间了。你知道该怎么做。这对你来说太懒了..
  • 它不是构建器模式,而更像是 Tom 所说的 Fluent API。
  • @kpie temp = new Classic(); 什么温度?我同意这是一个可以忽略的小缺陷,但在其他人指出之前,您的代码中也存在其他错误..

标签: java setter coding-style


【解决方案1】:

Method chaining 在某些情况下可能看起来不错,但我不会过度使用它。正如另一条评论中提到的,它确实在构建器模式中得到了很多使用。在某种程度上,这可能是个人喜好的问题。

在我看来,方法链接的一个缺点是调试和断点。单步执行由链式方法填充的代码可能会很棘手 - 但这也可能取决于 IDE。我发现调试能力绝对是至关重要的,所以我通常会避免在调试时让我的生活变得更加困难的模式和 sn-ps。

【讨论】:

  • +1 用于编写易于调试的代码,但如果您必须在 setter 上放置断点,您已经遇到了麻烦 ;-)
  • 呵呵我完全同意。我一般都在介绍方法链接。对于二传手,这可能只是个人喜好问题。我通常不会在构建器模式或类似模式之外使用它们。
  • 我很欣赏“方法链”的答案和 +1 但我真的在寻找关于性能的明确答案。
  • 或者你只是好奇... :)
  • 返回一些东西比不返回任何东西多带一条指令(或一些额外的指令),所以return this 稍微慢一些 - 如果你可以这样称呼它。 JVM 规范详细介绍了它的工作原理。不幸的是,我记不太清了,所以请用一小撮盐把它拿走。
【解决方案2】:

您在Alternative 类中使用的变体是我从“构建器模式”中知道的。在那里,任务是构建一些类似于builder.setX().setY().build() 的特定对象。

就个人而言,只要Alternative 变体没有特定用途,我就会使用Classic 变体。

(作为旁注,我不会为return 使用括号)

【讨论】:

  • Builder 模式的任务不是构建某个特定的对象,而是确保创建对象的整个操作一次发生,从而不会为任何不一致的状态留下空间。就像构造函数一样,它确保在其他人可以使用它之前使用所需的值初始化对象。与构造函数不同,它使代码特别是在大量参数的情况下更具可读性。
  • @bot "就像构造函数",或者像工厂方法:D.
  • @Tom 当然,但是工厂方法不一定会创建对象(它可以返回对由构造函数或其他工厂方法初始化的现有缓存对象的引用。我们永远不会知道:P)
【解决方案3】:

Java 中的 setter 最常与 JavaBeans 的概念相关联,尽管我们现在使用这个概念并没有像这样称呼它,但它确实经常在没有像这样显式命名的情况下使用,有时人们称它们为实体(即使没有ORM 上下文)。

JavaBean 具有属性,这些属性是combination of a private field and (a setter and/or a getter)。

对于这些 setter 和 getter,没有什么好说的,只是它们应该尽可能简单。在这方面,setter 最简单的实现是 void 之一:只需设置值并退出。

如果您查看任何 IDE 的功能,setter 的默认实现是 void。

在这方面,我总是使用void 方式获取值对象(无论它们被称为 JavaBeans、Entity、Dto 等),并且从不使用链接方式。您询问最佳实践,void-way 是价值对象的最佳实践。

对于工具,如构建器、dsl、服务、流,我可能会使用链接,前提是它确实有意义并且添加了一些东西并且不太麻烦。

我的简短建议是将void 用于值对象,并为其余部分做任何你想做的事情。享受设计课程的乐趣。 ;)

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 2011-02-26
    • 2013-08-05
    • 2011-12-02
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多