Mementoパターン
オブジェクトの状態を保存しておいて、後でその状態に戻すことができるようにするパターン
主に3つの要素で構成される
Originator
保持したい状態遷移をする対象
これの状態を遷移していき、前の状態を復元したい
Memento
Originatorの状態を保持するobject
状態の安全な保存と復元の仕組みを提供する
Caretaker
Mement[]を保持する
Originatorの状態が更新されたらMement[]にpushする
過去の任意の時点のMementを返却する
具体的なOriginatorの構造を知らない
Mementoの存在はかなりOOP色が強いmrsekut.icon
Originatorの内部状態を公開せずに、Originatorの状態を保持するために、
一度Mementoに変換して、保存し、復元できるようにしている
これは、そもそもimmutableなデータ構造を持ち回る言語等を使用していればMementoのような存在は必要ない
と、思ったが、そうでもないかmrsekut.icon
CaretakerがOriginatorの具体的な構造を知らないというのがポイントで
単純な3要素ぐらいから、複雑なOriginatorをconstructできる時に、
生成済みの複雑なoriginatorを丸ごと保存するのではなく、その3要素だけ保存できてりゃ良い
そのために一層必要になるが、それをMementoが担っている
サンプル
code:ts
const originator = new Originator("initial state");
const caretaker = new Caretaker();
caretaker.addMemento(originator.saveToMemento());
originator.printState(); // "Current state: initial state"
originator.setState("new state");
caretaker.addMemento(originator.saveToMemento());
originator.printState(); // "Current state: new state"
originator.restoreFromMemento(caretaker.getMemento(0));
originator.printState(); // "Current state: initial state"
Originator
code:ts
class Originator {
private state: string;
constructor(state: string) {
this.state = state;
}
public setState(state: string): void {
this.state = state;
}
public saveToMemento(): Memento {
return new Memento(this.state);
}
public restoreFromMemento(memento: Memento): void {
this.state = memento.getState();
}
public printState(): void {
console.log(Current state: ${this.state});
}
}
Memento
code:ts
class Memento {
private state: string;
constructor(state: string) {
this.state = state;
}
public getState(): string {
return this.state;
}
}
Caretaker
code:ts
class Caretaker {
private mementos: Memento[] = [];
public addMemento(memento: Memento): void {
this.mementos.push(memento);
}
public getMemento(index: number): Memento {
return this.mementosindex; }
}