C++备忘录模式:优雅实现对象状态保存与恢复

C++备忘录模式:优雅实现对象状态保存与恢复

C++备忘录模式:优雅实现对象状态保存与恢复

引言

在软件开发中,我们经常需要实现撤销操作、历史记录或状态回滚等功能。备忘录模式(Memento Pattern)正是为解决这类问题而生的设计模式。本文将深入探讨备忘录模式在C++中的实现与应用,帮助开发者掌握这一强大的设计工具。

备忘录模式概述

备忘录模式是一种行为设计模式,它允许在不破坏封装性的前提下捕获并外部化一个对象的内部状态,以便以后可以将该对象恢复到原先保存的状态【1†source】。该模式特别适合需要实现撤销操作、历史记录或快照功能的场景【1†source】【2†source】。

核心角色解析

1. Originator(发起人)

Originator是需要保存状态的对象,它:

  • 负责创建备忘录并记录当前状态
  • 可以使用备忘录恢复之前的状态
  • 知道如何正确保存和恢复自身状态【1†source】【2†source】

2. Memento(备忘录)

Memento是存储Originator状态的对象,特点包括:

  • 存储Originator的内部状态
  • 提供两个接口:宽接口(Originator使用)和窄接口(其他对象使用)【1†source】
  • 确保状态的封装性不被破坏

3. Caretaker(管理者)

Caretaker负责管理备忘录,其职责是:

  • 保存备忘录对象
  • 不操作备忘录内容
  • 只能通过窄接口与备忘录交互【1†source】

设计原则体现

备忘录模式很好地体现了多个面向对象设计原则:

  1. 单一职责原则:将状态保存的职责从Originator中分离出来【3†source】【7†source】,使Originator可以专注于核心业务逻辑【3†source】。
  2. 开闭原则:不需要修改Originator类就能扩展状态保存功能【3†source】,通过新增备忘录类实现这一扩展【3†source】。
  3. 迪米特法则:Caretaker不直接操作Memento内部细节【3†source】【6†source】,有效降低了系统耦合度【6†source】。

C++实现示例

#include<iostream>#include<string>#include<vector>// 备忘录类classMemento{private: std::string state;// 只有Originator可以访问私有成员friendclassOriginator;Memento(const std::string& s):state(s){} std::string GetState()const{return state;}};// 发起人类classOriginator{private: std::string state;public:voidSetState(const std::string& s){ std::cout <<"设置状态: "<< s << std::endl; state = s;} Memento*CreateMemento(){returnnewMemento(state);}voidRestoreFromMemento(const Memento* m){ state = m->GetState(); std::cout <<"恢复状态: "<< state << std::endl;}};// 管理者类classCaretaker{private: std::vector<Memento*> mementos; Originator* originator;public:Caretaker(Originator* orig):originator(orig){}~Caretaker(){for(auto m : mementos)delete m;}voidSave(){ mementos.push_back(originator->CreateMemento());}voidUndo(){if(mementos.empty())return; Memento* m = mementos.back(); originator->RestoreFromMemento(m); mementos.pop_back();delete m;}};// 使用示例intmain(){ Originator originator; Caretaker caretaker(&originator); originator.SetState("状态1"); caretaker.Save(); originator.SetState("状态2"); caretaker.Save(); originator.SetState("状态3");// 执行撤销 caretaker.Undo();// 恢复到状态2 caretaker.Undo();// 恢复到状态1return0;}

典型应用场景

备忘录模式在以下场景中特别有用:

  1. 撤销/重做功能:如文本编辑器中的撤销操作【1†source】【2†source】
  2. 事务回滚系统:数据库操作的事务管理【1†source】【5†source】
  3. 游戏存档系统:保存和恢复游戏进度【1†source】【2†source】
  4. 配置管理:保存和恢复系统配置状态

高级特性与优化

1. 增量备忘录

对于状态变化不大的场景,可以只保存变化部分【1†source】,这能显著减少内存消耗【1†source】。

2. 序列化支持

通过序列化技术,可以将备忘录状态持久化存储【2†source】,如保存到文件或数据库中【1†source】。

3. 线程安全考虑

在多线程环境中使用时【2†source】,需要添加适当的同步机制来保证状态的一致性【1†source】。

与其他模式的协作

备忘录模式常与其他设计模式配合使用:

  1. 命令模式:实现可撤销的操作【1†source】【2†source】
  2. 原型模式:通过克隆对象状态来优化备忘录创建【1†source】【2†source】
  3. 状态模式:保存不同状态配置【1†source】【2†source】

注意事项

  1. 内存消耗:对于大对象状态,需考虑内存使用情况【8†source】,可能影响系统性能【1†source】
  2. C++内存管理:特别注意指针和内存泄漏问题【1†source】【2†source】
  3. 替代方案:原型模式有时可作为更简单的替代方案【2†source】

总结

备忘录模式是面向对象设计原则的优秀实践【9†source】,通过状态封装实现了灵活的回滚机制【1†source】【2†source】。合理使用该模式可以显著提高系统的可维护性和扩展性【3†source】【7†source】。在C++中实现时,需要特别注意内存管理和线程安全等问题。掌握备忘录模式将帮助开发者构建更加强大、灵活的系统。

Read more

Git 一个本地仓库同时推送到两个远程仓库(详细教程)

Git 一个本地仓库同时推送到两个远程仓库(详细教程)

一. 引言 我们在实际工作中经常会涉及项目备份问题,尽管公司都有自己的仓库,但是呢很多情况下我们都还需要另外一个仓库。 一方面公司仓库通常需要公司内网或者链接VPN,有时候临时要用可能并不方便。 另一方面可能自己也希望备份一份,或者是一个仓库的成员不够用。 本篇博客会通过完整的实战步骤,来介绍如何实现Git双远程仓库同步。 二. 查看当前的远程仓库 执行命令: git remote -v 通常来讲输入如下: origin https://***@bitbucket.org/louis_private_project/ignoremodules.git (fetch) origin https://***@bitbucket.org/louis_private_project/ignoremodules.git (push) 这就表示现在只绑定了一个远程仓库。 它的含义是: * 拉取代码(fetch/pull) * 推送代码(push) Git 把拉取和推送地址分开显示了,默认情况下,pull 和

By Ne0inhk
OpenClaw六大开源替代方案深度解析,从极简原型到生产级巨兽的全面选型指南

OpenClaw六大开源替代方案深度解析,从极简原型到生产级巨兽的全面选型指南

在AI智能体领域,2025年无疑是属于“Claw”系列的一年。这一年11月,Peter Steinberger上传了一个名为OpenClaw的原型代码,谁也没想到,这个项目会在短短84天内收获20万颗GitHub Star,成为史上增长最快的软件项目。OpenClaw的爆火,就像一颗投入湖面的石子,瞬间激起了整个AI智能体生态的涟漪,一系列轻量级、针对性更强的开源替代方案纷纷涌现,它们各自在代码规模、安全性能、部署难度等维度上做出优化,满足不同开发者的多样化需求。 对于开发者而言,面对市面上五花八门的Claw类项目,如何根据自身的技术背景、部署环境和实际需求,选择最适合自己的方案,成为了一个亟待解决的问题。有的开发者追求极简代码,想快速理解AI智能体的核心逻辑;有的则看重安全性能,需要能直接用于生产环境的可靠方案;还有的专注于边缘计算,希望智能体能在资源受限的硬件上顺畅运行。为了帮大家理清思路,本文将对六大主流开源Claws项目进行深度对比,从项目概述、技术栈、性能指标到适用人群,再到部署要求和核心特性的差异,全方位解析每个项目的优势与不足,最后给出针对性的选型建议,希望能为开发者们

By Ne0inhk

New API 详解:新一代开源大模型统一网关与 AI 资产管理系统(深度 6000 字指南)

New API 详解:新一代开源大模型统一网关与 AI 资产管理系统(深度 6000 字指南) * 开篇:为什么我们需要一个“大模型统一网关”? * 一、项目背景与发展历程 * 二、核心特性详解(为什么 New API 比竞品强) * 1. 统一接口 + 多格式转换(最强兼容性) * 2. 智能路由与高可用 * 3. 精细计费与支付闭环(个人/企业必备) * 4. 现代化管理后台 * 5. 多语言 & 多租户 * 6. 扩展集成 * 7. 安全与可观测性 * 三、支持的模型与渠道(30+ 服务商,100+ 模型) * 四、部署安装完整教程(10 分钟上手)

By Ne0inhk
2025年ChipCamp芯片营地十大开源RISC-V

2025年ChipCamp芯片营地十大开源RISC-V

1、XiangShan ----官方地址:https://github.com/OpenXiangShan/XiangShan ----中科院计算所/中国科学院大学的开源RISC-V项目,面向RISC-V的最前沿技术和场景,使用Chisel语言,打造的高性能超标量乱序RISC-V处理器,经过雁栖湖,南湖,昆明湖多代版本的演进,代码和文档全部开源。 ----作为专业的超大规模RISC-V开源项目,在github上获得6.8K个star。 ----被ChipCamp收录在:https://gitcode.com/ChipCamp/XiangShan。 2、RISCV-BOOM ----官方地址:https://github.com/riscv-boom/riscv-boom ----在Github上有2K个星,其BOOM-v1.0代码在ChipCamp芯片营地行了通读。 ----被ChipCamp收录在:https://gitcode.com/ChipCamp/BOOM-v1.0。 3、e203_hbirdv2 ----官方地址(国际):https:

By Ne0inhk