zoukankan      html  css  js  c++  java
  • 16 行为型模式-----备忘录模式

    模式动机(Memento Pattern)我们在编辑文档时,经常需要将刚删除的内容恢复过来,这时最常用的就是撤销命令(Ctrl + Z)了,但是这种功能是如何实现的呢?

      可以猜想,其内部必然维护一个保存已删除内容的机制,这就是备忘录模式的用途了。

      其实在软件开发过程中,为了不同模块之间的交互,很多情况下需要记录一个对象内部状态的信息,以便可以进行恢复操作。比如,数据库的“回滚”操作,浏览器的“恢复上  一次”操作等。

    备忘录模式的一般定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样在某个时刻就可以将该对象恢复到原来的状态。

     

    模式结构图:

     

    模式代码:

    bt_备忘录模式.h:

     1 #ifndef MP_H
     2 #define MP_H
     3 #include <iostream>
     4 using namespace std;
     5 
     6 /*
     7     状态结构体
     8 */
     9 typedef struct State
    10 {
    11 public:
    12     State(int h = 0, int w = 0) : height(h), width(w){ };
    13     void SetState(int h, int w)
    14     {
    15         height = h;
    16         width = w;
    17     }
    18 
    19     int height;
    20     int width;
    21 }State;
    22 
    23 /*
    24     备忘录
    25 */
    26 class Memento
    27 {
    28 public:
    29    Memento(State* s)
    30    {
    31         state = new State(s->height, s->width);     // new出新状态执行深复制
    32   }
    33   ~Memento()
    34   {
    35       delete state;
    36   }
    37     State* GetState() const
    38     {
    39         return state;
    40     }
    41     void SetState(State* state)
    42     {
    43         this->state = state;
    44     }
    45 private:
    46     friend class Originator;
    47     State* state;
    48 
    49 };
    50 
    51 /*
    52     原发器
    53 */
    54 class Originator
    55 {
    56 public:
    57     Originator(State* s) : state(s){ }
    58     void SetMemento(const Memento* m)
    59     {
    60         this->state= m->GetState();
    61     }
    62     Memento* CreateMemento()
    63     {
    64         return new Memento(state);  // 此处若以指针类型的state传入构建新的备忘录,必须执行深复制,
    65                                     // 否则后期改变state时,备忘录中的state状态将会跟着改变;
    66                                     // 此外就是将state改为值传递形式,这样备忘录中保存的副本不受影响
    67     }
    68     // 显示当前状态
    69     void Show()
    70     {
    71         cout << "当前状态为:";
    72         cout << "height = " << state->height << ", " << "width = " << state->width << endl;
    73     }
    74 
    75 private:
    76     State* state;
    77 };
    78 
    79 /*
    80     管理者:负责保存、传递当前备忘录
    81 */
    82 class Caretaker
    83 {
    84 public:
    85     void SetMemento(Memento* m)
    86     {
    87         this->memento= m;
    88     }
    89     Memento* GetMemento()
    90     {
    91         return memento;
    92     }
    93 private:
    94     Memento* memento;
    95 };
    96 
    97 #endif // MP_H

     

    测试用例.cpp:

     1 #include "bt_备忘录模式.h"
     2 
     3 int main()
     4 {
     5     cout << "***** 备忘录模式测试 *****" << endl;
     6     State* s = new State(100, 50);
     7     Originator* original = new Originator(s);
     8     Caretaker* ct = new Caretaker();
     9     ct->SetMemento(original->CreateMemento());  // 用备忘录保存当前状态
    10     original->Show();
    11 
    12     cout << endl;
    13     s->SetState(200, 100);                      // 改变状态
    14     original->Show();
    15 
    16     cout << endl;
    17     original->SetMemento(ct->GetMemento());     // 恢复状态
    18     original->Show();
    19 
    20     delete ct;
    21     delete original;
    22     delete s;
    23 
    24     return 0;
    25 }
    
    

    模式分析:

    :: 备忘录用来存储原发器在前一时刻的内部状态,当需要设置恢复点时,管理者请求原发器创建一个备忘录,并记录原发器的当前状态。

    :: 备忘录的状态只有创建它的原发器可以修改,因此将原发器类设为备忘录的友元类,用于访问备忘录的私有数据。

    :: 管理者的作用是保存备忘录,必要时向原发器传递备忘录以恢复原发器的前一个状态。

    :: 备忘录模式实现了状态恢复功能,其将原发器的内部状态进行保存,而且只允许创建它的原发器进行修改,封装性较好,同时若在管理者中采用栈来保存多个备忘录就可以实现   多次撤销操作。

    :: 该模式与命令模式结合起来可以有效地实现撤销和重做命令,管理者可以利用STL容器来保存多个备忘录。

     

     

     

  • 相关阅读:
    糍粑大叔的独游之旅-战斗!之弹道实现
    攻击判定流程研究: 瀑布算法、圆桌算法、混合算法解析
    GitHub排名TOP30的机器学习开源项目/贪心学院
    学习ES7+ES8
    k8s Ipvs 内部网络自动分配和内部网络一致ip地址,导致ip冲突
    Linux操作系统load average过高,kworker占用较多cpu
    chrome断点调试&&其他技巧
    Mongodb更新数组$pull修饰符 (mongodb 修改器($inc/$set/$unset/$push/$pop/upsert))
    记一次线上Java程序导致服务器CPU占用率过高的问题排除过程
    解决并发问题,数据库常用的两把锁(转)
  • 原文地址:https://www.cnblogs.com/benxintuzi/p/4566399.html
Copyright © 2011-2022 走看看