"通过引用传递"是不是很糟糕的设计?

vma*_*yer 24 parameter-passing pass-by-reference

所以,我刚刚开始学习Java,我发现没有"通过引用传递"这样的东西.我正在将一个应用程序从C#移植到Java,原始应用程序有一个"ref"或"out"参数的整数和双精度数.

起初我以为我可以传入"整数"或"双精度",由于这是一个引用类型,因此值将被更改.但后来我了解到那些引用类型是不可变的.

那么,我创建了一个"MutableInteger"类和一个"MutableDouble"类,并将它们传递给了我的函数.它有效,但我想我必须违背该语言的原始设计意图.

一般糟糕的设计是"通过参考"吗?我该如何改变自己的思维方式?

拥有这样的函数似乎是合理的:

bool MyClass::changeMyAandB(ref int a, ref int b)
{
    // perform some computation on a and b here

    if (success)
        return true;
    else return false;
}
Run Code Online (Sandbox Code Playgroud)

这是糟糕的设计吗?

Kos*_*Kos 15

如果将代码构造成干净,可理解的抽象,则最好地完成面向对象的编程.

作为抽象的数字是不可变的并且没有身份(即"五"总是"五"而且没有"五个多个实例"这样的东西).

你想要发明的是一个"可变数字",它是可变的并具有同一性.这个概念有点笨拙,你可能会用更有意义的抽象(对象)建模你的问题.

在代表某些东西并具有特定界面的对象中思考,而不是在单个值的块中.


Fre*_*Foo 14

在一个支持它的语言中设计并不错,(*)但是当你必须定义一个MutableInt类只是为了在两个方法之间进行通信时,肯定是错误的.

您发布的示例的解决方案是返回两个整数的数组,并通过null返回或异常发出信号失败.这并不总是有效,所以有时你必须......

  • 设置当前对象的属性(当类中的两个方法进行通信时);
  • 传入一个整数数组,该方法可以修改(当有很多整数要传递多次时);
  • 比如创建一个帮助类,Result它封装了计算的结果(当你处理int一个float而不是两个整数时),并且可能将实际计算作为方法或构造函数;
  • 使用你建议的习语,但考虑在Apache Commons或其他好的库中使用它的支持.

(*)语言设计不好.在Python或Go中,您将返回多个值并停止担忧.


Chr*_*sic 6

通过引用传递值对象通常是一个糟糕的设计.

在某些情况下它是有效的,例如用于高性能排序操作的阵列位置交换.

您应该需要此功能的原因很少.在C#中,OUT关键字的使用通常是一个缺点.out关键字有一些可接受的用法,DateTime.TryParse(datetext, out DateValue)但out参数的标准用法是糟糕的软件设计,希望通常模拟使用标志作为状态的不良做法.

  • "通过引用传递值对象通常是一个糟糕的设计." 那么您还会考虑通过引用传递什么? (2认同)