跟踪时间的类可以是不可变的吗?

时间:2014-07-29 08:41:51

标签: oop time immutability

假设我在Java中有一个简单的类来存储时间戳:

public final class Timestamp {
  private final long value;

  public Timestamp(final long value) {
    this.value = value;
  }

  public long getValue() {
    return value;
  }
}

那是不可改变的。但是如果不是getValue()我会编写一个名为getProgress()的方法呢?

public final class Timestamp {
  private final long value;

  public Timestamp(final long value) {
    this.value = value;
  }

  public float getProgress() {
    return (SomeExternalPlace.getTimestamp() - value) / SomeFloatConstant;
  }
}

对象的状态永远不会改变,但getProgress() 的值会随时间发生变化。

后一类被认为是不可变的吗?为什么或为什么不呢?

1 个答案:

答案 0 :(得分:1)

它是不可变的,因为一旦创建了value的实例,其状态(Timestamp字段)就无法更改。时间戳表示某个时间点,无法更改。

从方法返回的数据不一定必须始终相同。

此外,Timestamp展示了您对不可变对象所期望的所有属性(例如,线程安全性)。

这是不可变性的另一个“奇怪”的例子:

class LazyList<T>
{
    private readonly T _head;
    private LazyList<T> _tail;
    private readonly Func<LazyList<T>> _tailDelegate;

    private bool _created;

    public LazyList(T head, Func<LazyList<T>> tailDelegate)
    {
        _head = head;
        _tailDelegate = tailDelegate;
        _created = false;
    }

    public T GetHead()
    {
        return _head;
    }

    public LazyList<T> GetTail()
    {
        if(! _created)
        {
            _tail = _tailDelegate();
            _created = true;
        }

        return _tail;
    }
}

正如您所看到的,_tail不是真正不可变 - 当实例化LazyList<T>时它为空,并且仅在客户端调用{{1}时才分配}。但那真的没关系。一旦尾部被创建,它就不会改变;在此之前,尾巴仍然“存在”,它还没有实现。

这实际上是Scala的不可变Stream的实现方式。