行为型之备忘录模式C++实现

2022-06-16 15:51:43 浏览数 (2)

显示需求:每个人都有犯错误的时候,都希望有种“后悔药”能弥补自己的过失,让自己重新开始,但现实是残酷的。

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

优点:

  • 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
  • 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。

缺点:

资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

主要角色:

  1. 发起人:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
  2. 备忘录:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
  3. 管理者:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

具体案例:小码路一毕业就被家里崔着相亲,一天,小码路看了三个姑娘,分别是红红,绿绿和蓝蓝,突然不知所措了,选了这个又想选那个,呵,男人。这时候媒婆说可以后悔一次,重新选吧。

第一步:备忘录

代码语言:javascript复制
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

//备忘录:相亲对象
class Girl
{
    public:
        Girl(string name)//4
        {
            this->name=name;
            cout<<"name" << name<<endl;
        }
        void SetGirlName(string name)
        {
            this->name=name;
        }
        string GetGirlName()
        {  
            cout<<"getgirlname"<<name<<endl;
            return name;
        }
    private:
        string name;
};

第二步:发起者

代码语言:javascript复制
//发起者:小码路
class XiaoMaLu
{
    public:
        void SetGirl(string name)
        {
            GirlName = name;
            cout<<"GirlName: "<<GirlName<<endl;
        }
        string GetGirl()
        {
            return GirlName;
        }
        Girl* CreateMemento()//3
        {  
            return new Girl(GirlName);
        }
        void RestoreMemento(Girl *g)
        {
            SetGirl(g->GetGirlName());
        }

    private:
        string GirlName;
};

第三步:管理者

代码语言:javascript复制
//管理者
class GirlStack
{  
    public:
        GirlStack(){//1
            top = -1;
        }
        bool push(Girl *g)
        {  
            if(top >= 4)
            {
                cout<<"小码路你太花心了吧!能不能找到对象呀!"<<endl;
                return false;
            }
            else
            {
                girl[  top] = g;
                cout<<"top: "<<top<<endl;
                return true;
            }
            
        }
        Girl* pop()
        {
            if(top <= 0)
            {
                cout<<"相亲对象没有了!"<<endl;
                return girl[0];
            }
            else
            {   
                return girl[top--];
            }
                
        }
    private:
        Girl *girl[5];
        int top;
};

//相亲去了
class Dating{

public:
    Dating()
    {
        cout<<"备忘录模式进行相亲"<<endl;
        xml = new XiaoMaLu();
        girls = new GirlStack();
       
        Select(0);
        girls->push(xml->CreateMemento());
        cout<<" 小码路选的妻子名字是: "<<xml->GetGirl()<< endl;
        Select(1);//后悔了 退货
        cout<<" 后悔过后, 小码路选的妻子名字是: "<<xml->GetGirl()<< endl;
    }
    void ShowGirl(string name)
    {
        xml->SetGirl(name);
    }
    void Select(int s)//2
    {
        bool ok=false;
        if(s == 0)//挑选美女
        {   
            ok = girls->push(xml->CreateMemento()); //保存状态
            cout<<"ok= "<< ok<<endl;
            if(ok && girl1.compare("红红") == 0 )
            {   
                ShowGirl("红红");  
                
            }
             if(ok && girl2.compare("花花") == 0 )
            {
                ShowGirl("花花");
            }
             if(ok && girl3.compare("黄黄") == 0 )
            {
                ShowGirl("黄黄");
            }
             if(ok && girl4.compare("蓝蓝") == 0 )
            {
                ShowGirl("蓝蓝");
            }
        }

        else if(s == 1)//后悔了 恢复原来状态
        {
            xml->RestoreMemento(girls->pop());
            ShowGirl(xml->GetGirl());
        }
       
    }

    private:
        XiaoMaLu *xml;
        GirlStack *girls;
        string girl1="红红",girl2="花花",girl3="黄黄",girl4="蓝蓝";

};

int main()
{
    Dating *dating = new Dating();
}

结果显示:

0 人点赞