设计模式之备忘录

news/2024/9/24 19:16:46/

一、备忘录设计模式概念

备忘录模式(Memento) 是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

 适用场景

  • 当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。
  • 当直接访问对象的成员变量、 获取器或设置器将导致封装被突破时, 可以使用该模式。

备忘录设计模式的结构

  1. 原发器 (Originator) 类可以生成自身状态的快照, 也可以在需要时通过快照恢复自身状态。

  2. 备忘录 (Memento) 是原发器状态快照的值对象 (value object)。 通常做法是将备忘录设为不可变的, 并通过构造函数一次性传递数据。

  3. 负责人 (Caretaker) 仅知道 “何时” 和 “为何” 捕捉原发器的状态, 以及何时恢复状态。

    负责人通过保存备忘录栈来记录原发器的历史状态。 当原发器需要回溯历史状态时, 负责人将从栈中获取最顶部的备忘录, 并将其传递给原发器的恢复 (restoration) 方法。

  4. 在该实现方法中, 备忘录类将被嵌套在原发器中。 这样原发器就可访问备忘录的成员变量和方法, 即使这些方法被声明为私有。 另一方面, 负责人对于备忘录的成员变量和方法的访问权限非常有限: 它们只能在栈中保存备忘录, 而不能修改其状态。

代码如下:

        问题:实现一个游戏的存档功能。希望在保存状态的同时可以不破坏类的封装。
        解决方案:在不破坏封装性的前提下,捕获一个对象内部的状态,并在该对象之外保存这个状态。
        这样以后就可将该对象恢复到原先保存的状态。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
//Memento
class Memento
{friend class Hero;
private:unsigned int m_state;std::string m_data;public:Memento(unsigned int state) :m_state(state) {std::time_t now = std::time(0);m_data = std::ctime(&now);}std::string getData(){return m_data;}
};//Originator
class Hero
{
private:unsigned int m_state;
public:Hero(unsigned int state):m_state(state){std::cout << "英雄:我的初始状态为:" << m_state << std::endl;}void fight(){std::cout << "英雄:战斗中..." << std::endl;m_state -= std::rand() % 20;std::cout << "英雄:战斗后状态为:" << m_state << std::endl;}Memento* save(){return new Memento(m_state);}void restore(Memento* memento){m_state = memento->m_state;std::cout << "英雄:恢复状态为:" << m_state << std::endl;}
};//Caretaker
class Caretaker
{
private:Hero* hero;std::vector<Memento*> m_mementos;
public:Caretaker(Hero* hero){this->hero = hero;}~Caretaker(){for (auto m : m_mementos){delete m;}}void backup(){std::cout << "管理者:正在保存英雄状态..."  << std::endl;m_mementos.push_back(hero->save());}void undo(){if (!m_mementos.size() > 0){return;}Memento* memento = m_mementos.back();m_mementos.pop_back();std::cout << "管理者:正在恢复英雄状态..." <<memento->getData()<< std::endl;hero->restore(memento);delete memento;}
};
int main()
{std::srand(static_cast<unsigned int>(std::time(NULL)));Hero* hero=new Hero(100);Caretaker* caretaker=new Caretaker(hero);caretaker->backup();hero->fight();hero->fight();caretaker->backup();hero->fight();caretaker->undo();delete hero;delete caretaker;
}

 二、与其他模式的关系

  • 你可以同时使用命令模式 (opens new window)和备忘录模式 (opens new window)来实现 “撤销”。 在这种情况下, 命令用于对目标对象执行各种不同的操作, 备忘录用来保存一条命令执行前该对象的状态。
  • 你可以同时使用备忘录 (opens new window)和迭代器模式 (opens new window)来获取当前迭代器的状态, 并且在需要的时候进行回滚。
  • 有时候原型模式 (opens new window)可以作为备忘录 (opens new window)的一个简化版本, 其条件是你需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。

http://www.ppmy.cn/news/1529936.html

相关文章

解决【WVP服务+ZLMediaKit媒体服务】加入海康摄像头后,能发现设备,播放/点播失败,提示推流超时!

环境介绍 每人搭建的环境不一样&#xff0c;情况不一样&#xff0c;但是原因都是下面几种&#xff1a; wvp配置不当网络端口未放开网络不通 我搭建的环境&#xff1a; WVP服务&#xff1a;windows下&#xff0c;用idea运行的源码 ZLM服务&#xff1a;虚拟机里 问题描述 1.…

使用Go语言的互斥锁(Mutex)解决并发问题

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在并发编程中,由于存在竞争条件和数据竞争,我们需要将某些代码片段设定为临界区,并使用互斥锁(Mutex)等同步原语来保护这些临界区。本文将详细介绍Go语言标准库中Mutex的使用方法,以及如何利用它来解决实际…

Mysql的基本常识,DDL以及基本数据类型

数据类型&#xff1a; 数值类型&#xff1a; 数值类型大小范围TINYINT1 byte(-128,127)SMALLINT2 byte(-32768,31767)MEDIUMINT3 byte(-8388608,8388607)INT 或者 INTEGER4 byteBIGINT8 byteFLOAT4 byteDOUBLE8 byte 还有一个特殊一点的&#xff1a;DECIMAL 他的大小和范围依…

前后端分离集成CAS单点登录

修改nginx worker_processes 1; events {worker_connections 1024; } http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 80;server_name localhost;location /api/ {proxy_pass htt…

前端CSS学习框架

⭐️ CSS &#x1f4ac; 描述&#xff1a;层叠样式表&#xff0c;用于设计风格和布局。 &#x1f4da; 资源&#xff1a;学习使用 CSS 为 HTML 添加样式 - 学习 Web 开发 | MDN ⭐️ 基本语法 ⭐️ 引入方式 行内样式 内部样式表 外部样式表 ⭐️ 选择器 通用选择器 标签…

排序算法Java实现

文章目录 排序算法概述比较排序算法非比较排序算法稳定 vs 不稳定Java 中的排序 外部排序1) 冒泡排序2) 选择排序3) 堆排序4) 插入排序5) 希尔排序6) 归并排序递归实现时间复杂度非递归实现 7) 归并插入8) 快速排序随机基准点处理重复值 9) 计数排序10) 桶排序11) 基数排序 排序…

Spring MVC 启动与请求处理流程解析

Spring MVC 是一个基于 Java 的实现 MVC 设计模式的 Web 框架&#xff0c;它是 Spring 框架的一个模块&#xff0c;用于构建 Web 应用程序。Spring MVC 的启动过程主要涉及以下几个步骤&#xff1a; &#xff08;看流程图会比较直观一些&#xff09; #mermaid-svg-KLVe3JEll2OL…

1466C/D/E/G/H信号发生器

1466C/D/E/G/H 信号发生器 频率范围&#xff1a;6kHz~110GHz 产品综述 Ceyear 1466系列信号发生器是一款面向微波毫米波尖端测试的通用测试仪器&#xff0c;频率范围覆盖宽、信号频谱纯度高&#xff0c;具有高准确度和大动态范围的功率输出&#xff0c;搭配单机双射频通道的…