+TypeScript 예제
이력 관리자는 스냅샷을 보관하고, TextEditor만 그 스냅샷의 내용과 복원 방법을 안다. 과거 상태를 보관하려고 편집기의 내부 문자열을 외부에 풀어놓지 않도록 역할을 나눈다.
type ISnapshot = Readonly<{ kind: "snapshot" }>;
// 복원할 상태의 해석과 변경은 원본 편집기 안에 둔다.
class TextEditor {
#text = "";
readonly #snapshots = new WeakMap<ISnapshot, string>();
get text(): string { return this.#text; }
write(text: string): void { this.#text = text; }
// 외부에는 보관용 토큰만 주고 실제 문자열은 비공개 저장소에 남긴다.
save(): ISnapshot {
const token = Object.freeze({ kind: "snapshot" as const });
this.#snapshots.set(token, this.#text);
return token;
}
restore(snapshot: ISnapshot): boolean {
const text = this.#snapshots.get(snapshot);
if (text === undefined) return false;
this.#text = text;
return true;
}
}
const editor = new TextEditor();
editor.write("draft");
const saved = editor.save();
editor.write("new");
console.log(editor.restore(saved));
console.log(editor.text);
console.log(new TextEditor().restore(saved));
true
draft
false
TypeScript에서는 불변 토큰과 편집기별 비공개 WeakMap으로 스냅샷 내부를 감췄다. 토큰의 겉모양만 흉내 내거나 다른 편집기의 토큰을 넘겨도 복원되지 않는다.