当前位置: 首页 > news >正文

备忘录模式(Memento Pattern)

备忘录模式(Memento Pattern)

1. 知识点总结

备忘录模式是一种行为型设计模式,核心思想是:

在不破坏对象封装性的前提下,捕获对象的内部状态并保存在外部,以便后续能够将对象恢复到之前的状态。

它最常见的应用就是撤销(Undo)/重做(Redo)功能,比如文本编辑器、游戏存档、数据库事务回滚等。

模式中有三个核心角色:

角色 职责
Originator(发起人) 拥有需要保存的状态,提供创建备忘录和恢复状态的方法
Memento(备忘录) 封装 Originator 的内部状态,对外隐藏细节
Caretaker(管理者) 负责保存和恢复备忘录,不直接操作备忘录内容

适用场景

  • 需要实现撤销/重做功能;
  • 需要保存对象的历史快照,支持回滚;
  • 事务执行失败时需要还原到执行前的状态。

优缺点

优点 缺点
不破坏封装性,外部无法随意修改备忘录状态 频繁保存大对象会消耗较多内存
状态保存逻辑与业务逻辑分离 管理者需要维护备忘录集合,可能引入额外复杂度
容易实现多步撤销/重做 需要谨慎处理深拷贝与浅拷贝问题

2. 示例代码

下面用一个简单的文本编辑器来演示:每次写入后保存快照,误操作后可以通过历史栈撤销。

package mainimport "fmt"// Editor 是发起人(Originator),拥有需要被保存的内部状态。
type Editor struct {content string
}func (e *Editor) Write(text string) {e.content += text
}func (e *Editor) Content() string {return e.content
}// Save 创建一份备忘录,封装当前内容。
func (e *Editor) Save() Memento {return Memento{snapshot: e.content}
}// Restore 根据备忘录恢复状态。
func (e *Editor) Restore(m Memento) {e.content = m.snapshot
}// Memento 是备忘录,只暴露给 Caretaker 和 Originator 使用。
// 这里通过未导出字段限制外部直接修改快照内容。
type Memento struct {snapshot string
}// History 是管理者(Caretaker),负责维护备忘录的历史栈。
type History struct {stack []Memento
}func (h *History) Save(m Memento) {h.stack = append(h.stack, m)
}func (h *History) Undo() (Memento, bool) {if len(h.stack) == 0 {return Memento{}, false}last := h.stack[len(h.stack)-1]h.stack = h.stack[:len(h.stack)-1]return last, true
}func main() {editor := &Editor{}history := &History{}editor.Write("Hello ")history.Save(editor.Save())fmt.Printf("写入后: %q\n", editor.Content())editor.Write("World!")history.Save(editor.Save())fmt.Printf("再次写入后: %q\n", editor.Content())editor.Write(" 这是多余内容")fmt.Printf("误操作后: %q\n", editor.Content())if m, ok := history.Undo(); ok {editor.Restore(m)fmt.Printf("撤销一次后: %q\n", editor.Content())}if m, ok := history.Undo(); ok {editor.Restore(m)fmt.Printf("再撤销一次后: %q\n", editor.Content())}
}

3. 运行结果

写入后: "Hello "
再次写入后: "Hello World!"
误操作后: "Hello World! 这是多余内容"
撤销一次后: "Hello World!"
再撤销一次后: "Hello "

4. 关键点复盘

  1. 封装性是第一原则:备忘录的 snapshot 字段没有导出,外部(包括 Caretaker)不能直接修改快照内容,只能通过 Originator 的 Save/Restore 来操作。
  2. Caretaker 只负责保管History 不知道备忘录里具体存了什么,也不应该去解析它,这样 Originator 的内部结构变化不会影响历史管理逻辑。
  3. 栈是实现撤销的常用结构:每次保存时入栈,撤销时出栈并恢复;如果要支持重做,可以再加一个 redo 栈。
  4. 注意深拷贝:如果 Originator 的状态包含引用类型(切片、Map、指针),保存备忘录时需要进行深拷贝,否则快照会被后续修改污染。
  5. 与命令模式的区别:备忘录模式通过保存状态快照来撤销;命令模式通常通过记录逆操作来撤销。状态简单时用备忘录更直接,操作复杂时命令模式更灵活。
http://www.jsqmd.com/news/1325711/

相关文章:

  • SpringBoot+Vue校园疫情防控系统开发实践
  • 2026年河北教师编培训机构挑选攻略:陌上教育及头部品牌实测梳理 - 八方八方
  • Linux内核工作队列深度解析:从INIT_WORK到异步任务处理实践
  • 北京私生子女抚养权律所:隐私保护与亲子鉴定程序 - 品牌深度评测
  • Spring-AI-Alibaba记忆功能架构与实战指南
  • 西安交大吴宁教授《大学计算机基础》48讲:零基础构建系统知识体系
  • 2026年热门外卖骑手兼职平台排名与接单指南 - 企业信息速递
  • Oracle归档日志路径查询全解析:从基础命令到实战避坑指南
  • SpringBoot+SSM构建学生过程性作业评价系统实践
  • 从“创始人投影“到“真理映射“:反认知殖民时代的真理制度设计——基于贾子体系(TMM / LWEVSD / THL / KICS)的元批判框架
  • Java多智能体框架AgentScope:构建高效协作AI系统的核心架构与实践
  • ESP8266/ESP32 WiFi模块Web配网:从原理到代码实现与优化
  • 2026 年镇江中考复读学校推荐怎么选?南京天元中考复读学校值得考虑吗 - GrowUME
  • 2026年,哪些电子围栏企业能以超高性价比脱颖而出?快来一探究竟!
  • 企业AI网关采购合同的12个隐藏条款
  • 成都红惯货架定制工厂运输货架厂家地址电话推荐|双流区空港四路2299号现场核对|营业时间与到店前准备|2026年8月4日资料更新 - mobible
  • 2026氢能源电解槽龙门多头中频点焊机:靠谱合作厂家推荐 - 汇聚至此
  • 微信AI助手开发指南:从零搭建智能聊天机器人
  • C++20宏革新:__VA_OPT__特性解析与应用实践
  • 二叉树算法实战:Leetcode高频题解析与优化技巧
  • Python爬虫实战:从jj20.com批量下载高清壁纸的完整方案
  • 2026年8月郑州靠谱的合同纠纷律师怎么选?葛晓清律师精细化梳理交易证据化解合作分歧 - 专业优选推荐榜
  • 企业定制皮具礼品,如何用更合理的成本拿到更高品质的交付?
  • 项目文档:基于深度迁移学习的阿尔茨海默病MRI影像分类系统研究与实现
  • 如何选择乌鲁木齐装修设计 本地设计团队口碑参考 - 八方八方
  • BBWEYY 低成本获客转化解决方案:SaaS应用市场规则变化,软件公司如何获得独立企业客户,含零代码SAAS、AI编程、源码定制交付
  • 从零构建实时弹幕系统:Python+Flask+Socket.IO实现抽象弹幕模拟与管理
  • 掌握B站视频下载技巧:DownKyi开源工具全方位使用指南
  • 2026年选美标穿线管?看这份厂商口碑红黑榜再定 - GrowUME
  • 2026年全国互联网服务企业资质核验结果公示 - 招财兔数字员工