Jak*_*nce 3 java oop immutability
在Java中,按照标准的代码风格和设计原则,什么时候修改对象的内部数据比较合适,什么时候用修改后的数据新建一个对象比较合适呢?
例如,假设我有一个类 Vector2D,它包含一个 x 分量和一个 y 分量,我想旋转该向量:
public class Vector2D{
private int x;
private int y;
public Vector2D(int x, int y){
this.x = x;
this.y = y;
}
public void rotate(double angle){
//code for finding rotated vector
x = rotated_x;
y = rotated_y;
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以旋转 Vector2D 对象 vector1.rotate(angle)
public class Vector2D{
private final int x;
private final int y;
public Vector2D(int x, int y){
this.x = x;
this.y = y;
}
public Vector2D rotate(double angle){
//code for finding rotated vector
Vector2D rotated = new Vector2D(rotated_x, rotated_y);
return(rotated);
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以旋转 Vector2D 对象 vector1 = vector1.rotate(angle)
到目前为止,我对这个问题的研究使我相信方法 B 对于允许方法链很有用,例如vector1 = vector1.rotate(angle).scale(scalar)
,它有自己的好处,更多的是在可读性方面。
这也让我意识到方法 B 允许您使对象不可变,所以我想通过扩展我的问题也是:
什么时候让对象不可变是合适的,尤其是在这个例子中?(一般来说,对于点、向量、多边形等。所有这些类型都应该是不可变的吗?)
我在创建这篇文章时想到的项目是一个游戏,其中实体由多边形表示,并使用向量进行操作。
我相信由于预期的应用程序,确保类是线程安全的应该不是问题,因为 Vector 和 Polygon 数据无论如何都应该由逻辑线程更改。
这也意味着对于每个实体,这些操作可能每秒执行 60 次(每个游戏周期)。这是否意味着每次实例化新对象的任何开销都会迅速增加?
通常,您应该更喜欢使对象不可变。您可能想要选择可变对象的原因是:
pandas
例如 - 它提供了两种选择)。 shuffle
,即使您不担心(1),也最好改变列表,因为如果您返回副本会令人惊讶。一些语言和库提出了第三种方式,其中变异返回对象的新“版本”,同时共享先前的状态(请参阅参考资料)。这解决了 (1),从而使您可以从不变性中受益,而无需进行大量复制。有人认为这意味着您实际上应该始终选择不变性,因为随着 (1) 的消失,除了熟悉之外,不再有任何理由选择可变性。实际上,有些算法在没有可变状态的情况下很难表达(例如,参见this)。所以我们可能会继续拥有可变状态。