21. 备忘录模式(Memento)

问题:需要保存和恢复对象之前的状态(如撤销操作、存档)。

核心:在不破坏封装的前提下,捕获对象的内部状态并外部存储。

class EditorMemento {
  constructor(public readonly content: string) {}
}

class Editor {
  #content: string = '';
  type(text: string): void { this.#content += text; }
  getContent(): string { return this.#content; }
  save(): EditorMemento { return new EditorMemento(this.#content); }
  restore(memento: EditorMemento): void { this.#content = memento.content; }
}

const editor = new Editor();
editor.type('你好');
editor.type('世界');
console.log(editor.getContent()); // 你好世界

const saved = editor.save();
editor.type('!');
console.log(editor.getContent()); // 你好世界!

editor.restore(saved);
console.log(editor.getContent()); // 你好世界
package memento

import "fmt"

type Memento struct {
  content string
}

func (m Memento) Content() string { return m.content }

type Editor struct {
  content string
}

func (e *Editor) Type(text string) { e.content += text }

func (e *Editor) GetContent() string { return e.content }

func (e *Editor) Save() Memento {
  return Memento{content: e.content}
}

func (e *Editor) Restore(m Memento) {
  e.content = m.Content()
}

// 使用
// editor := &Editor{}
// editor.Type("你好")
// editor.Type("世界")
// saved := editor.Save()
// editor.Type("!")
// editor.Restore(saved)
// fmt.Println(editor.GetContent()) // 你好世界

实战场景

  • 文本编辑器撤销:每次关键编辑保存文档快照或增量状态,撤销时恢复到旧状态。
  • 画布编辑:移动、缩放、删除、组合图层后保存快照,支持撤销和历史版本。
  • 游戏存档:保存角色属性、地图位置、任务进度、背包状态,之后可以恢复。
  • 表单草稿:用户填写到一半离开页面,保存当前字段状态,下次继续编辑。
  • 配置回滚:系统发布新配置前保存旧配置,发现问题后快速恢复。
  • 事务补偿:复杂业务流程执行前保存关键对象状态,失败时恢复或生成补偿操作。
  • 向导步骤:多步骤表单每一步保存状态,用户返回上一步时不丢数据。
  • 临时预览:用户调颜色、布局、权限策略时先保存原状态,取消预览时恢复。
  • 调试断点:调试器保存程序当前执行状态、变量和调用栈,方便暂停与恢复。
  • 离线编辑:本地保存多个草稿版本,网络恢复后选择合并或回滚到某个版本。