设计模式(20)备忘录模式

备忘录模式简介

使用Git的时候,代码有问题了,可以checkout到上一个版本,备忘录模式就是这种机制,用户可以方便的制定恢复到指定的某个历史状态。

Ctrl + Z 就是一种备忘录模式。

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

备忘录模式结构

在这里插入图片描述
备忘录模式主要有以下角色:

  • Originator(原发器):通过创建一个备忘录类存储当前的内部状态,也可以使用备忘录来恢复其内部状态,通常是将系统中需要保存内部状态的类设计为原发器;
  • Memento(备忘录):用于存储原发器的内部状态。备忘录的设计可以参考原发器的设计,根据需要确定备忘录类中的属性;除了原发器类对象,不允许其他对象修改备忘录。
  • Caretaker(负责人):负责保存备忘录,可以存储一个或多个备忘录对象,但是负责人只负责保存对象,不能修改对象,也不必知道对象的实现细节。

备忘录模式代码实例

#include <iostream>

using namespace std;

class RoleStateMemento
{
    
    
public:
     RoleStateMemento(unsigned iBlood, unsigned iAttack, unsigned iDefense) : m_iBlood(iBlood), m_iAttack(iAttack), m_iDefense(iDefense){
    
    }

private:
     friend class GameRole;

     unsigned GetBloodValue() {
    
     return m_iBlood; }
     unsigned GetAttackValue() {
    
     return m_iAttack; }
     unsigned GetDefenseValue() {
    
     return m_iDefense; }

     unsigned m_iBlood;   // 生命力
     unsigned m_iAttack;  // 攻击力
     unsigned m_iDefense; // 防御力
};

class GameRole
{
    
    
public:
     GameRole() : m_iBlood(100), m_iAttack(100), m_iDefense(100){
    
    }

     // 存档
     RoleStateMemento *SaveState() {
    
     return new RoleStateMemento(m_iBlood, m_iAttack, m_iDefense); }

     // 恢复存档
     void RecoveryState(RoleStateMemento *pRoleState)
     {
    
    
          m_iBlood = pRoleState->GetBloodValue();
          m_iAttack = pRoleState->GetAttackValue();
          m_iDefense = pRoleState->GetDefenseValue();
          cout<<"Recovery..."<<endl;
     }

     void ShowState()
     {
    
    
          cout<<"Blood:"<<m_iBlood<<endl;
          cout<<"Attack:"<<m_iAttack<<endl;
          cout<<"Defense:"<<m_iDefense<<endl;
     }

     void Fight()
     {
    
    
          m_iBlood -= 100;
          m_iAttack -= 10;
          m_iDefense -= 20;

          if (m_iBlood == 0)
          {
    
    
               cout<<"Game Over"<<endl;
          }
     }

private:
     unsigned m_iBlood;   // 生命力
     unsigned m_iAttack;  // 攻击力
     unsigned m_iDefense; // 防御力
};

class RoleStateCaretaker
{
    
    
public:
     void SetRoleStateMemento(RoleStateMemento *pRoleStateMemento) {
    
     m_pRoleStateMemento = pRoleStateMemento; }
     RoleStateMemento *GetRoleStateMemento() {
    
     return m_pRoleStateMemento; }

private:
     RoleStateMemento *m_pRoleStateMemento;
};

int main()
{
    
    
     GameRole *pLiXY = new GameRole(); // 创建李逍遥这个角色
     pLiXY->ShowState(); // 显示初始的状态

     // 存档
     RoleStateCaretaker *pRoleStateCaretaker = new RoleStateCaretaker();
     pRoleStateCaretaker->SetRoleStateMemento(pLiXY->SaveState());

     // 开始打大BOSS
     pLiXY->Fight();
     pLiXY->ShowState();

     // 读档,从新开始
     pLiXY->RecoveryState(pRoleStateCaretaker->GetRoleStateMemento());
     pLiXY->ShowState();

     return 0;
}

备忘录模式总结

优点:

  • 实现状态恢复、撤销操作的功能,用户可以恢复到指定的历史状态,让软件系统更加人性化;
  • 备忘录封装了信息,除了原生器以外,其他对象访问不了备忘录的代码;

缺点:

  • 资源消耗大。如果需要保存原生器对象的多个历史状态,那么将创建多个备忘录对象;或者如果原生器对象的很多状态都需要保存,也将消耗大量存储资源。

适用环境:

  • 保存一个对象的历史状态,系统需要设计回退或者撤销功能;
  • 备忘录类可以封装一个对象的历史状态,避免对象的历史状态被外界修改。

猜你喜欢

转载自blog.csdn.net/qq_24649627/article/details/115487315