热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++设计模式——备忘录模式(MementoPattern)

C设计模式——备忘录模式(MementoPattern)微信公众号:幼儿园的学霸目录文章目录C设计模式——备忘录模式(MementoPattern)目录定义代码示例总
C++设计模式——备忘录模式(Memento Pattern)

微信公众号:幼儿园的学霸


目录

文章目录

  • C++设计模式——备忘录模式(Memento Pattern)
  • 目录
  • 定义
  • 代码示例
  • 总结
  • 参考资料


定义

Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

备忘录模式:保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

备忘录模式主要应用于备份或者回退操作,为了使软件使用更友好,通常都有回退功能,软件一般也要提供回退机制,而要实现回退,就必须事先备份好状态信息,所以有了备忘录模式就有实现系统回退到某一个特定的历史状态。

备忘录对象用于存储另外一个对象内部状态的快照对象,所以备忘录模式又可以称之为快照模式(Snapshot Pattern)或Token模式

其UML类图如下所示:
备忘录模式UML类图
主要角色如下:

  • 备忘录角色(Memento): 负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人;
  • 发起人角色(Originator): 记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,可以根据需要决定备忘录角色中保存自身的哪些内部状态,能够访问备忘录里的所有信息;
  • 管理者角色(Caretaker): 对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改,只能够将备忘录传递给其他对象。

代码示例

游戏存档为例,看一下如何用备忘录模式实现

#include //
//备忘录模式
//关键代码:Memento类、Originator类、Caretaker类;
// Originator类不与Memento类耦合,而是与Caretaker类耦合
////需要保存的信息
//此处将需要保存的信息提取出来放在一个结构体中
//也可以不用放在结构体中,直接作为类的成员变量
typedef struct {int nHp;//血量int nMp;//蓝量int nAttack;//攻击
}GameValue;//备忘录类
class Memento{
public:Memento(const GameValue& gameValue):m_gameValue(gameValue){}//函数前后均加const//前const:返回的变量不可修改//后const:该函数readonly,表示该类的this指针为const类型,// 不能改变类的成员变量的值const GameValue& getValue() const{return m_gameValue;}//Memento() = delete;//Memento(const Memento &) = delete;//Memento &operator=(const Memento &) = delete;private:GameValue m_gameValue;
};//管理者角色
class Caretaker
{
public:const std::shared_ptr GetState(const std::string& key) {return mData[key];}void SetState(const std::string& key,std::shared_ptr pMemento) {mData[key] = pMemento;}private://此处考虑在map中存储指针,而非直接存储对象std::map> mData;
};//发起人角色
class Hero{
public:Hero():m_gameValue{100,100,100}{}Hero(const GameValue& gameValue):m_gameValue(gameValue){}//保存当前信息void saveState(const std::string& key) {m_Caretaker.SetState(key, std::make_shared(m_gameValue));}//恢复信息const void resumeState(const std::string& key) {m_gameValue &#61; m_Caretaker.GetState(key)->getValue();}void battle(){m_gameValue.nHp &#61; rand()%100;m_gameValue.nMp &#61; rand()%100;m_gameValue.nAttack &#61; rand()%100;}void showState() {std::cout<<"血量&#xff1a;"<};int main()
{Hero hero;std::cout<<"----战斗前-----"<}

总结

  • 备忘录模式与原型模式&#xff1a;
    原型模式也能保存一个对象在某一个时刻的状态&#xff0c;那么两者有何不同的呢&#xff1f;原型模式保存的是当前对象的所有状态信息&#xff0c;恢复的时候会生成与保存的对象完全相同的另外一个实例&#xff1b;而备忘录模式保存的是我们关心的在恢复时需要的对象的部分状态信息&#xff0c;相当于快照。

  • 优点&#xff1a; 1.给用户提供了一种可以恢复状态的机制&#xff0c;可以使用户能够比较方便地回到某个历史的状态; 2.实现了信息的封装&#xff0c;使得用户不需要关心状态的保存细节。

  • 缺点&#xff1a;消耗资源。如果类的成员变量过多&#xff0c;势必会占用比较大的资源&#xff0c;而且每一次保存都会消耗一定的内存。

  • 使用场景&#xff1a; 1、需要保存/恢复数据的相关状态场景;2、提供一个可回滚的操作。

  • 应用实例&#xff1a; 1.Windows 里的 ctri &#43; z&#xff1b;2.浏览器的后退&#xff1b;3.虚拟机的快照与恢复&#xff1b;4.git版本管理&#xff1b;5.棋牌游戏的悔牌操作。


参考资料

1.备忘录模式&#xff08;详解版&#xff09;
2.备忘录模式(Memento)C&#43;&#43;实现



下面的是我的公众号二维码图片&#xff0c;按需关注
图注:幼儿园的学霸


推荐阅读
  • 开发笔记:图像识别基于主成分分析算法实现人脸二维码识别
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了图像识别基于主成分分析算法实现人脸二维码识别相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 本文介绍了在实现了System.Collections.Generic.IDictionary接口的泛型字典类中如何使用foreach循环来枚举字典中的键值对。同时还讨论了非泛型字典类和泛型字典类在foreach循环中使用的不同类型,以及使用KeyValuePair类型在foreach循环中枚举泛型字典类的优势。阅读本文可以帮助您更好地理解泛型字典类的使用和性能优化。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 点击上方“新机器视觉”,选择加”星标”或“置顶”重磅干货,第一时间送达很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间。去年有过一段时间的集中学习,做 ... [详细]
  • WPF之Binding初探
      初学wpf,经常被Binding搞晕,以下记录写Binding的基础。首先,盗用张图。这图形象的说明了Binding的机理。对于Binding,意思是数据绑定,基本用法是:1、 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
    原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ... [详细]
author-avatar
nana-Wang2602915845
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有