快照

在某個時間點檢視物件

2004 年 3 月 7 日

這是 進一步的企業應用程式架構開發 寫作的一部分,我是在 2000 年代中期撰寫的。遺憾的是,自那時起有太多其他事情吸引了我的注意力,所以我沒有時間進一步研究它們,而且在可預見的未來我也看不到太多時間。因此,這些材料很大程度上仍處於草稿形式,而且在我能夠找到時間再次研究它們之前,我不會進行任何更正或更新。

運作方式

快照只不過是移除所有時間面向的物件檢視。因此,如果完整的時間物件具有 getAddress(date) 形式的存取器,則快照將具有 getAddress() 存取器。快照的所有問題都是非時間性的。

建立快照時,您需要提供適當的日期。如果存在雙時間性,則您需要實際日期和記錄日期。

快照是協助存取的檢視,因此在大多數情況下,它們應該是不可變的。例外情況是您可能會更新快照,然後在某個日期將其套用回實際物件。這不是我經常做的事情,通常只在與不了解時間性的外部系統一起工作時才會這樣做。

何時使用

時間性會為設計增加相當大的複雜性,有時您不想考慮到這一點。也許您處於一個環境中,您希望針對特定時間點進行大量工作,而且您不想一直提醒系統您正在處理哪個時間點。或者,您正在連結到不了解時間性的系統。然後,您可以建立快照以與該系統一起使用。

進一步閱讀

當我與安迪·卡爾森合作撰寫我們的 plop 論文 時,這個模式對我來說變得清晰。

範例:實作快照 (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 的建構函式來建立快照,提供客戶和實際日期。您也可以透過呼叫客戶端的 createSnapshot(Date) 方法來執行此操作。使用建構函式可讓您避免客戶端對其快照的依賴性。