快照

在某一时间点对一个对象的视图

2004年3月7日

这是我在2000年代中期进行的进一步的企业应用程序架构开发写作的一部分。遗憾的是,此后太多其他事情吸引了我的注意力,所以我没有时间进一步研究它们,而且在可预见的未来我也没有看到太多时间。因此,这些材料非常草稿形式,我不会进行任何更正或更新,直到我能找到时间再次处理它。

工作原理

一个快照仅仅是一个对象在去除所有时间方面后的视图。因此,如果完整的时间对象具有形式为getAddress(date)的访问器,那么快照将具有访问器getAddress()。快照的所有问题都是非时间性的。

创建快照时,需要提供一个适当的日期。如果存在双时间性,则需要实际日期和记录日期。

快照是一种用于访问的视图,因此在大多数情况下它们应该是不可变的。一个例外是,您可能会更新快照,然后将其应用回真实对象,就像在某个日期一样。这不是我经常做的事情,通常只在与不了解时间性的外部系统合作时才会这样做。

何时使用它

时间性会给设计增加相当大的复杂性,有时您不想考虑这一点。也许您处于一个想要对特定时间点进行大量工作的环境中,并且不想不断提醒系统您正在处理哪个时间点。或者,也许您正在链接到一个不了解时间性的系统。然后,您可以为该系统拍摄快照。

进一步阅读

与安迪·卡尔森合作撰写我们的plop paper时,这个模式对我来说很清晰。

示例:实现快照(Java)

将快照组合在一起非常简单。关键是使用委托,以便快照充当底层对象的适配器。

图 1:使用委托实现快照

class Customer...

  private TemporalCollection addresses = new SingleTemporalCollection();
  public Address getAddress(MfDate date) {
    return (Address) addresses.get(date);
  }
  public Address getAddress() {
    return getAddress(MfDate.today());
  }
  public void putAddress(MfDate date, Address value) {
    addresses.put(date, value);
  }

class CustomerSnapshot...

  private Customer base;
  private MfDate validDate;
  public CustomerSnapshot (Customer base, MfDate validDate) {
    this.base = base;
    this.validDate = validDate;
  }
  public Address getAddress() {
    return base.getAddress(validDate);
  }

请注意,在这种情况下,您通过在CustomerSnapshot上调用构造函数并提供客户和实际日期来创建快照。您也可以通过在 Customer 上调用createSnapshot(Date)方法来实现。使用构造函数可以避免 Customer 与其快照之间的依赖关系。