Java中的Setter约定(return void或this)

fhg3lkii  于 2023-05-15  发布在  Java
关注(0)|答案(4)|浏览(131)

我写Java已经快一年了,我看到了人们如何实现setter的两种不同的约定。
为了说明这一点,这里有两个约定的示例。(我也想知道这两种模式的简洁名称)
使用第一约定的类从它们的“set”方法中不返回任何内容。就像这样:

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

这是有争议的,哪一个更可读/可用。
我的问题是关于这两种模式之间的性能差异。它存在吗?如果是这样的话,差异有多大,它是从哪里产生的?
如果没有性能差异,哪一个被认为是“更好的实践”?

gudnpqoy

gudnpqoy1#

Method chaining在某些情况下可能看起来不错,但我不会过度使用它。正如在另一条评论中提到的,它在构建器模式中得到了大量的使用。在某种程度上,这可能是个人偏好的问题。
在我看来,方法链的一个缺点是调试和断点。单步执行充满链式方法的代码可能很棘手-但这也可能取决于IDE。我发现调试的能力绝对至关重要,所以我通常会避免使用模式和代码片段,因为它们可能会使我在调试时的工作变得更加困难。

yeotifhr

yeotifhr2#

你在类Alternative中使用的变体是我从“构建器模式”中知道的。在那里,任务是构建一些类似于builder.setX().setY().build()的特定对象。
就我个人而言,只要Alternative变体没有特定用途,我就会使用Classic变体。
(As附带说明,我不会对return使用括号)

o2g1uqev

o2g1uqev3#

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,对其他对象做任何你想做的事情。祝你设计课程愉快。;)

ou6hu8tu

ou6hu8tu4#

不能说,什么选择具有更好的性能。有些人可能会认为,我通常称之为流畅接口(参见https://en.wikipedia.org/wiki/Fluent_interface)的替代方案具有更差的性能,因为this指针必须一次又一次地返回。但这纯粹是推测。
不能给出一般性的答案。

  • 函数或方法调用的开销相对较高。返回一个指针只是其中可以忽略的一部分。
  • Java不仅在编译时进行优化。例如,有一些技术可以在运行时删除变量或内联函数或方法调用(也可以比较Are there inline functions in java?)。
  • 如果性能真的很重要,代码的作者需要在他的示例上运行一个分析器。如果这真的确定了瓶颈,那么值得考虑专门的功能(例如只在一个方法中设置x和y)或完全不使用setter函数。
  • 如果程序的某些部分需要专门的机制,那么在任何地方也使用这些机制都是不合适的。这种特殊格式的方法是否合适的问题通常不是执行性能的问题。
  • 在这个例子中,setx和sety的好处是什么并不清楚。在给出答案之前,了解这一点很重要。看起来当成员变量公开时,这些方法可以被消除。这当然是最有效的解决方案。
  • 如果不清楚这些要点,这个问题看起来更像是这个讨论的一个示例:https://wiki.c2.com/?PrematureOptimization

没有给出一个答案,什么是“更好”的做法,我想,大家都同意,无效版本是最常见的做法。通常情况下,最好也遵循常见的做法(https://de.wikipedia.org/wiki/Principle_of_Least_Surprise)。但这并不意味着,这实际上是最好的做法。返回this-pointer不会伤害任何人,在某些情况下是有用的。

相关问题