cover

Memento 模式:狀態的時間點快照

Memento 模式允許物件在不破壞封裝的前提下保存狀態,方便撤銷或回復。

classDiagram
    class Originator {
        -state : any
        +setState(state) void
        +getState() any
        +saveToMemento() Memento
        +restoreFromMemento(memento) void
    }
    class Memento {
        -state : any
        -timestamp : Date
        +getState() any
    }
    class Caretaker {
        -mementos : Memento[]
        +addMemento(memento) void
        +getMemento(index) Memento
    }
    Originator ..> Memento : 建立快照
    Caretaker o-- Memento : 保管歷史

使用情境

  1. 編輯器撤銷:保存歷史狀態。
  2. 流程回滾:回到某個操作節點。

實作範例

Memento 模式:保存快照與回復狀態

class Memento {
  constructor(state) {
    this.state = state;
    this.timestamp = new Date();
  }
 
  getState() {
    return this.state;
  }
}
 
class Originator {
  constructor() {
    this.state = null;
  }
 
  setState(state) {
    console.log(`Setting state to: ${state}`);
    this.state = state;
  }
 
  getState() {
    return this.state;
  }
 
  saveToMemento() {
    return new Memento(this.state);
  }
 
  restoreFromMemento(memento) {
    this.state = memento.getState();
    console.log(`State restored to: ${this.state}`);
  }
}
 
class Caretaker {
  constructor() {
    this.mementos = [];
  }
 
  addMemento(memento) {
    this.mementos.push(memento);
  }
 
  getMemento(index) {
    return this.mementos[index];
  }
}
 
const originator = new Originator();
const caretaker = new Caretaker();
 
originator.setState('State #1');
caretaker.addMemento(originator.saveToMemento());
 
originator.setState('State #2');
caretaker.addMemento(originator.saveToMemento());
 
originator.restoreFromMemento(caretaker.getMemento(0));

優點

  • 可保存狀態而不破壞封裝
  • 撤銷/回復容易實作

缺點

  • 狀態大時耗記憶體
  • 需要管理保存時機

延伸閱讀