<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C++ 備忘錄模式 - 開啟月光寶盒

          共 1648字,需瀏覽 4分鐘

           ·

          2020-10-14 19:41

          備忘錄模式(Memento Pattern)在不破壞封裝的前提下,捕獲一個對象的內部狀態(tài),并在該對象之外保存這個狀態(tài),這樣可以在以后將對象恢復到原先保存的狀態(tài)。



          1

          模式結構


          UML 結構圖:



          • Originator(發(fā)起人):負責創(chuàng)建一個 Memento,以記錄當前時刻自身的內部狀態(tài),并可以使用 Memento 恢復內部狀態(tài)。Originator 可以根據(jù)需要決定 Memento 儲存自己的哪些內部狀態(tài)。

          • Memento(備忘錄):負責存儲 Originator 對象的內部狀態(tài),并可以防止 Originator 以外的其他對象訪問備忘錄。

          • Caretaker(管理者):負責管理 Memento,但不能對 Memento 的內容進行訪問或者操作。



          2

          優(yōu)缺點



          優(yōu)點:


          • 提供了一種狀態(tài)恢復機制,使用戶能夠方便地回到某個歷史的狀態(tài)。

          • 實現(xiàn)了信息的封裝,使得用戶不需要關心狀態(tài)的保存細節(jié)。



          缺點:


          • 如果 Originator 對象很大,那么 Memento 對象也會很大,這勢必會占用較大的存儲空間,而且每保存一次都需要消耗一定的系統(tǒng)資源。



          3

          適用場景


          • 保存一個對象在某一個時刻的全部(或部分)狀態(tài),這樣在以后需要時便能夠恢復到先前的狀態(tài),實現(xiàn)撤銷操作。

          • 防止外界對象破壞一個對象歷史狀態(tài)的封裝性,避免將對象歷史狀態(tài)的實現(xiàn)細節(jié)暴露給外界對象。



          4

          案例分析




          月光寶盒 - 讓時光倒流





          很多人說年少時看《大話西游》,看著看著就笑了;長大之后再看,看著看著就哭了。無論是笑了還是哭了,心中總有很多疑惑無法解開。


          《大話西游》依托于“月光寶盒”,構建了幾個平行時空中發(fā)生的愛情故事。其中,有一個經典橋段:

          至尊寶在盤絲洞找到盤絲大仙留下的月光寶盒,此時牛魔王帶白晶晶來到盤絲洞。白晶晶以為春三十娘和二當家生下的孩子是她和至尊寶所生,憤而自刎。至尊寶為了救白晶晶,使用月光寶盒使時光倒流,幾次后產生故障,竟將其帶回五百年前,這時紫霞仙子向他走來 …

          和“月光寶盒”一樣,備忘錄模式也提供了時光倒流的機制,將一個對象某個時刻的狀態(tài)進行備份,當用戶后悔(需要返回之前的狀態(tài))時,可以把備份調用出來!



          5

          代碼實現(xiàn)



          創(chuàng)建備忘錄


          穿越至某一時刻,這個時刻指具體的日期時間,用 DateTime 表示,并為其提供相應的 setter 和 getter 方法:


          //?memento.h
          #ifndef?MEMENTO_H
          #define?MEMENTO_H

          #include?
          #include?

          //?日期時間
          class?DateTime
          {

          public:
          ????DateTime(std::string?dt)?:?m_dateTime(dt)?{}
          ????~DateTime()?{}

          ????void?SetDateTime(std::string?dt)?{
          ????????m_dateTime?=?dt;
          ????}

          ????std::string?GetDateTime()?{
          ????????return?m_dateTime;
          ????}

          private:
          ????std::string?m_dateTime;
          };

          #endif?//?MEMENTO_H



          創(chuàng)建發(fā)起人


          Life 用于創(chuàng)建 DateTime,以記錄當前的日期時間,并可以使用 DateTime 進行恢復:


          //?originator.h
          #ifndef?ORIGINATOR_H
          #define?ORIGINATOR_H

          #include?"memento.h"
          #include?
          #include?

          //?一生
          class?Life
          {

          public:
          ????Life()?{}
          ????~Life()?{}

          ????void?SetDateTime(std::string?dt)?{
          ????????std::cout?<"Set?date?time?to?"?<std::endl;
          ????????m_dateTime?=?dt;
          ????}

          ????//?僅用于打印
          ????std::string?GetDateTime()?{
          ????????return?m_dateTime;
          ????}

          ????//?恢復日期時間
          ????void?SetMemento(DateTime?*dt)?{
          ????????if?(nullptr?!=?dt)
          ????????????m_dateTime?=?dt->GetDateTime();
          ????}

          ????//?創(chuàng)建日期時間
          ????DateTime?*CreateMemento()?{
          ????????return?new?DateTime(m_dateTime);
          ????}

          private:
          ????std::string?m_dateTime;
          };

          #endif?//?ORIGINATOR_H



          創(chuàng)建管理者


          這是時光倒流的關鍵,通過 PandoraBox,至尊寶才可以彌補遺憾:


          //?originator.h
          #ifndef?CARE_TAKER_H
          #define?CARE_TAKER_H

          #include?"originator.h"
          #include?

          //?月光寶盒
          class?PandoraBox
          {

          public:
          ????PandoraBox(Life?*life)?:?m_pLife(life)?{}
          ????~PandoraBox()?{
          ????????for?(auto?itr?=?m_history.begin();?itr?!=?m_history.end();?++itr)?{
          ????????????delete?*itr;
          ????????}
          ????????m_history.clear();
          ????}

          ????//?保存?zhèn)浞?/span>
          ????void?Save()?{
          ????????m_history.push_back(m_pLife->CreateMemento());
          ????}

          ????//?穿越至某一時刻(隨機取時間)
          ????void?Undo()?{
          ????????int?index?=?rand()?%?m_history.size();
          ????????m_pLife->SetMemento(m_history[index]);
          ????}

          private:
          ????Life?*m_pLife;
          ????std::vector?m_history;
          };

          #endif?//?CARE_TAKER_H



          創(chuàng)建客戶端


          想啟動“月光寶盒”,體驗一把穿越的感覺?大聲喊出那句爛熟于心的“般bō若rě波羅蜜”:


          //?main.cpp
          #include?"originator.h"
          #include?"care_taker.h"
          #include?
          #include?

          #ifndef?SAFE_DELETE
          #define?SAFE_DELETE(p)?{?if(p){delete(p);?(p)=NULL;}?}
          #endif

          int?main()
          {
          ????srand((unsigned)time(0));

          ????Life?*life?=?new?Life();
          ????PandoraBox?*box?=?new?PandoraBox(life);

          ????//?設置并保存一些歷史時間
          ????for?(int?i?=?0;?i?5;?i++)?{
          ????????std::ostringstream?buffer;
          ????????buffer?<"200"?<"/10/01?00:00:00";
          ????????std::string?dt?=?buffer.str();

          ????????life->SetDateTime(dt);
          ????????box->Save();
          ????}

          ????//?穿越多次
          ????for?(int?i?=?0;?i?2;?i++)?{
          ????????box->Undo();
          ????????std::cout?<"Current?date?time?is?"?<GetDateTime()?<std::endl;
          ????}

          ????SAFE_DELETE(life);
          ????SAFE_DELETE(box);

          ????getchar();

          ????return?0;
          }


          輸出如下:

          Set date time to 2000/10/01 00:00:00

          Set date time to 2001/10/01 00:00:00

          Set date time to 2002/10/01 00:00:00

          Set date time to 2003/10/01 00:00:00

          Set date time to 2004/10/01 00:00:00

          Current date time is 2001/10/01 00:00:00

          Current date time is 2003/10/01 00:00:00


          ·END·

          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久岛国电影免费观看软件 | 国产AV日韩AV | 看尻屄视频| 国产精品成人小视频 | 免费 无码 国产 |