【第17节】C++设计模式(行为模式)-Memento(备忘录)模式

一、问题引出

使用 Memento 模式实现撤销操作

在软件开发中,用户在执行某些关键操作时,可能会希望有"撤销"功能,以便在操作失误时能够恢复到之前的状态。Memento 模式正是为了解决这一问题而设计的。该模式允许在不破坏封装性的前提下,捕获并保存一个对象的内部状态,从而在需要时恢复该状态。

二、Memento 模式概述

Memento 模式的核心思想是在不暴露对象内部结构的情况下,保存对象的内部状态。通过这种方式,用户可以在需要时将对象恢复到之前的状态。Memento 模式通常由三个角色组成:

(1)Originator(原发器): 负责创建一个 Memento 对象,用以保存当前状态,并可以使用 Memento 对象恢复到之前的状态。
(2)Memento(备忘录): 用于存储 Originator 的内部状态。
**(3)Caretaker(管理者):**负责保存 Memento 对象,但不能对 Memento 的内容进行操作或检查。

三、Memento 模式的实现

代码实现

以下是使用 C++ 实现的 Memento 模式的完整代码示例。代码分为三个部分:`Memento.h`、`Memento.cpp` 和 `main.cpp`。

Memento.h

cpp 复制代码
#ifndef _MEMENTO_H_
#define _MEMENTO_H_

#include <string>
using namespace std;

class Memento;

// Originator 类
class Originator {
public:
    typedef string State;

    Originator();
    Originator(const State& sdt);
    ~Originator();

    Memento* CreateMemento();  // 创建备忘录
    void RestoreToMemento(Memento* mt);  // 恢复到备忘录状态
    State GetState();
    void SetState(const State& sdt);
    void PrintState();

private:
    State _sdt;  // 当前状态
};

// Memento 类
class Memento {
public:
    friend class Originator;  // 将 Originator 声明为友元类,以便访问私有成员

private:
    typedef string State;

    Memento(const State& sdt);  // 构造函数
    void SetState(const State& sdt);  // 设置状态
    State GetState();  // 获取状态

private:
    State _sdt;  // 保存的状态
};

#endif //~_MEMENTO_H_

Memento.cpp

cpp 复制代码
#include "Memento.h"
#include <iostream>
using namespace std;

// Originator 类的实现
Originator::Originator() {
    _sdt = "";
}

Originator::Originator(const State& sdt) {
    _sdt = sdt;
}

Originator::~Originator() {}

Memento* Originator::CreateMemento() {
    return new Memento(_sdt);
}

Originator::State Originator::GetState() {
    return _sdt;
}

void Originator::SetState(const State& sdt) {
    _sdt = sdt;
}

void Originator::PrintState() {
    cout << this->_sdt << "....." << endl;
}

void Originator::RestoreToMemento(Memento* mt) {
    this->_sdt = mt->GetState();
}

// Memento 类的实现
Memento::Memento(const State& sdt) {
    _sdt = sdt;
}

void Memento::SetState(const State& sdt) {
    _sdt = sdt;
}

Memento::State Memento::GetState() {
    return _sdt;
}

main.cpp

cpp 复制代码
#include "Memento.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) {
    Originator* o = new Originator();
    o->SetState("old");  // 设置初始状态
    o->PrintState();  // 打印当前状态

    Memento* m = o->CreateMemento();  // 创建备忘录
    o->SetState("new");  // 修改状态
    o->PrintState();  // 打印修改后的状态

    o->RestoreToMemento(m);  // 恢复到备忘录状态
    o->PrintState();  // 打印恢复后的状态

    delete o;
    delete m;

    return 0;
}

代码说明

(1)封装性: Memento 模式的关键在于封装性。Memento 类的接口被声明为 `private`,只有 Originator 类可以访问它。这确保了对象状态的封装性,其他类无法直接访问或修改 Memento 中的状态。
(2)状态保存与恢复: Originator 类通过 `CreateMemento` 方法创建 Memento 对象来保存当前状态,并通过 `RestoreToMemento` 方法恢复到之前的状态。
**(3)测试程序:**在 `main.cpp` 中,我们演示了如何使用 Memento 模式来实现状态的保存和恢复。Originator 的状态从 `old` 变为 `new`,最后又恢复为 `old`。

四、总结讨论

Memento 模式常用于需要实现撤销操作的场景,尤其是在 Command 模式中。通过 Memento 模式,可以轻松地实现多级撤销操作。此外,Memento 模式还可以用于实现快照功能,即在某些关键点保存对象的状态,以便在需要时恢复。

Memento 模式提供了一种简单而有效的方式来保存和恢复对象的状态,同时保持了对象的封装性。通过该模式,用户可以在软件系统中实现"撤销"功能,从而提升用户体验。在实际开发中,Memento 模式可以与其他设计模式(如 Command 模式)结合使用,以实现更复杂的功能。

相关推荐
hetao17338377 小时前
2026-04-09~12 hetao1733837 的刷题记录
c++·算法
6Hzlia7 小时前
【Hot 100 刷题计划】 LeetCode 136. 只出现一次的数字 | C++ 哈希表&异或基础解法
c++·算法·leetcode
汉克老师7 小时前
GESP2024年6月认证C++三级( 第二部分判断题(1-10))
c++·数组·位运算·补码·gesp三级·gesp3级
无限进步_8 小时前
【C++】只出现一次的数字 II:位运算的三种解法深度解析
数据结构·c++·ide·windows·git·算法·leetcode
小贾要学习8 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
哎嗨人生公众号9 小时前
手写求导公式,让轨迹优化性能飞升,150ms变成9ms
开发语言·c++·算法·机器人·自动驾驶
code_whiter9 小时前
C++6(模板)
开发语言·c++
一只旭宝9 小时前
【C++ 入门精讲1】初始化、const、引用、内联函数 | 超详细手写笔记(附完整代码)
开发语言·c++
旖-旎10 小时前
哈希表(字母异位次分组)(5)
数据结构·c++·算法·leetcode·哈希算法·散列表
无限进步_10 小时前
【C++】多重继承中的虚表布局分析:D类对象为何有两个虚表?
开发语言·c++·ide·windows·git·算法·visual studio