《设计模式的艺术》笔记 - 备忘录模式

介绍

        备忘录模式在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为模式,别名为Token。

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>
#include <unordered_map>
#include <atomic>
#include <vector>
#include <memory>

class Originator;
class Memento { // 备忘录类
    friend Originator;  // 备忘录只能由Originator创建,确保安全
private:
    Memento();
    Memento(Originator *o);
    void setState(const std::string &state);
    std::string &getState();
private:
    std::string m_state;
};

class Originator {  // 原发器类,需要保存状态
public:
    Originator();

    std::shared_ptr<Memento> createMemento();

    void restoreMemento(const std::shared_ptr<Memento> &m);

    void setState(const std::string &state);

    std::string &getState();

private:
    std::string m_state;
};

class Caretaker {   // 负责人类,管理备忘录
public:
    std::shared_ptr<Memento> &getMemento();
    void setMemento(std::shared_ptr<Memento> m);

private:
    std::shared_ptr<Memento> m_memento;
};

#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"
#include <thread>
#include <unistd.h>
#include <sstream>

Memento::Memento(Originator *o) {
    m_state = o->getState();
}

void Memento::setState(const std::string &state) {
    m_state = state;
}

std::string& Memento::getState() {
    return m_state;
}

Originator::Originator() {

}

std::shared_ptr<Memento> Originator::createMemento() {
    std::shared_ptr<Memento> m(new Memento(this));
    return m;
}

void Originator::restoreMemento(const std::shared_ptr<Memento> &m) {
    setState(m->getState());
}

void Originator::setState(const std::string &state) {
    m_state = state;
}

std::string& Originator::getState() {
    return m_state;
}

void Caretaker::setMemento(std::shared_ptr<Memento> m) {
    m_memento = m;
}

std::shared_ptr<Memento>& Caretaker::getMemento() {
    return m_memento;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Originator *originator = new Originator();
    originator->setState("初始状态");
    auto m0 = originator->createMemento();
    originator->setState("第一次状态");
    auto m1 = originator->createMemento();
    originator->setState("第二次状态");
    auto m2 = originator->createMemento();
    Caretaker *caretaker = new Caretaker();

    std::cout << "恢复状态前:" << std::endl;
    std::cout << "\t" << originator->getState() << std::endl;

    std::cout << "第一次恢复:" << std::endl;
    caretaker->setMemento(m2);
    originator->restoreMemento(caretaker->getMemento());
    std::cout << "\t" << originator->getState() << std::endl;

    std::cout << "第二次恢复:" << std::endl;
    caretaker->setMemento(m1);
    originator->restoreMemento(caretaker->getMemento());
    std::cout << "\t" << originator->getState() << std::endl;

    std::cout << "第三次恢复:" << std::endl;
    caretaker->setMemento(m0);
    originator->restoreMemento(caretaker->getMemento());
    std::cout << "\t" << originator->getState() << std::endl;

    delete originator;
    delete caretaker;

    return 0;
}

总结

优点

        1. 它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤。当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

        2. 备忘录实现了对信息的封装。一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

缺点

        1. 资源消耗过大。如果需要保存的原发器类的成员变量太多,就不可避免地需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。

适用场景

        1. 保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时就能够恢复到先前的状态,实现撤销操作。

        2. 防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。

练习

略(参考实现部分)

相关推荐

  1. 设计模式艺术笔记 - 备忘录模式

    2024-01-24 15:14:01       33 阅读
  2. 设计模式艺术笔记 - 原型模式

    2024-01-24 15:14:01       35 阅读
  3. 设计模式艺术笔记 - 适配器模式

    2024-01-24 15:14:01       36 阅读
  4. 设计模式艺术笔记 - 外观模式

    2024-01-24 15:14:01       34 阅读
  5. 设计模式艺术笔记 - 组合模式

    2024-01-24 15:14:01       25 阅读
  6. 设计模式艺术笔记 - 装饰模式

    2024-01-24 15:14:01       31 阅读
  7. 设计模式艺术笔记 - 命令模式

    2024-01-24 15:14:01       34 阅读
  8. 设计模式艺术笔记 - 策略模式

    2024-01-24 15:14:01       35 阅读
  9. 设计模式艺术笔记 - 状态模式

    2024-01-24 15:14:01       29 阅读
  10. 设计模式艺术笔记 - 模板方法模式

    2024-01-24 15:14:01       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-24 15:14:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-24 15:14:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-24 15:14:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-24 15:14:01       20 阅读

热门阅读

  1. Oracle中TO_DATE与TO_CHAR区别

    2024-01-24 15:14:01       38 阅读
  2. Oracle 数据库恢复删除的数据

    2024-01-24 15:14:01       41 阅读
  3. 软件工程测试3

    2024-01-24 15:14:01       35 阅读
  4. 融资项目——EasyExcel将Excel文件保存至数据库

    2024-01-24 15:14:01       35 阅读