Java中不可变和可变对象的设计

Oli*_*ire 2 java class-design mutable immutability

我的问题涉及API设计.

假设我正在设计一个矢量(数学/物理意义).我想要一个不可变的实现和一个可变的实现.

然后我的矢量看起来像这样:

public interface Vector {
  public float getX(); public float getY();
  public X add(Vector v);
  public X subtract(Vector v);
  public X multiply(Vector v);
  public float length();
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何确保同时具有可变和不可变的实现.我真的不喜欢java.util.List的方法(默认允许可变性)和Guava的不可变实现所具有的UnsupportedOperationException().

如何使用这两种实现设计"完美"接口或抽象类Vector?

我想过这样的事情:

public interface Vector {
  ...
  public Vector add(Vector v);
  ...
}
public final class ImmutableVector implements Vector {
  ...
  public ImmutableVector add(Vector v) {
    return new ImmutableVector(this.x+v.getX(), this.y+v.getY());
  }
  ...
}
public class MutableVector implements Vector {
  ...
  public MutableVector add(Vector v) {
    this.x += v.getX();
    this.y += v.getY();
    return this;
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

总而言之,我想检查这种方法是否存在明显的设计缺陷,这些缺陷是什么,我应该怎么做才能解决这些问题?


注意:"向量"的东西是一个更通用的用例的例子.为了我的问题,我可以选择重写List接口或其他任何东西.请关注更一般的用例.


最终选择,在下面的答案之后,基于Joda-time,如有人解释但现在编辑:

/** Basic class, allowing read-only access. */
public abstract class ReadableVector {
  public abstract float getX(); public abstract float getY();
  public final float length() {
    return Vectors.length(this);
  }
  // equals(Object), toString(), hashCode(), toImmutableVectors(), mutableCopy()
}
/** ImmutableVector, not modifiable implementation */
public final class ImmutableVector extends ReadableVector implements Serializable {
  // getters
  // guava-like builder methods (copyOf, of, etc.)
}
/** Mutable implementation */
public class Vector extends ReadableVector implements Serializable {
  // fields, getters and setters
  public void add (ReadableVector v) {/* delegate to Vectors */}
  public void subtract(ReadableVector v) {/* delegate to Vectors */}
  public void multiply(ReadableVector v) {/* delegate to Vectors */}
}
/** Tool class containing all the logic */
public final class Vectors {
  public static ImmutableVector add(ReadableVector v1, ReadableVector v2) {...}
  public static void addTo(Vector v1, ReadableVector v2) {...}
  ...
}
Run Code Online (Sandbox Code Playgroud)

我将Vector从接口更改为抽象类,因为基本上vector不应该是其他任何东西.

谢谢大家.

Paŭ*_*ann 7

作为Vector库的用户,我不希望有一个add修改当前Object的add实现和另一个返回新实现的实现(同一个接口).

最好有一组明确的方法,不修改当前对象,然后在可变向量中有其他方法来修改当前对象.