zoukankan      html  css  js  c++  java
  • 设计模式--备忘录模式C++实现

    备忘录模式C++实现

    1定义Memento pattern

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

    2类图

    3实现

    class Originator

    {

    private:

      string state;

    public:

      string getState();

      void setState(string &x);

      Memento creatMemento()

      {

        return new Memento(state);

      }

      void restoreMemento(Memento men)

      {

        setState(men.getState());

      }

    };

    class Memento

    {

    public:

      Memento(string st)

        :state(st)

      {}

      string getState()

      {

        return state;

      }

      void setState(string st)

      {

        state = st;

      }

    };

    //备忘录管理员角色

    class Caretaker

    {

    private:

      Memento memento;

      Memento getMemento()

      {return memento;}

      void setMemento(string st)

      {memento = st;}

    };

    class Client
    {

    public:

      void operator()()

      {

        Originator or= new Originator();

        Caretaker ca = new Caretaker();

        //管理员备忘记录设置为用户定义为备忘状态

        ca.setMemento(or.createMemento());

        //用户重新会退到管理员记录的某一状态

        or.restoreMemento(ca.getMemento());

      }

    };

    4应用

    使用场景

    需要提供保存和恢复数据的相关状态场景

    提供一个可回滚rollback操作

    需要监控的副本场景。

    数据库连接的事务管理就是备忘录模式

    注意事项:

    备忘录的声明期:作用在最近的代码。不使用就立即删除。..备忘录不是华佗在世,起死回生

    备忘录的性能:不能用在for中,不能用频繁建立。消耗资源太多,这会是设计重构的前兆

    5扩展

    clone方式的备忘录

    实现

    class Originator :public Cloneable

    {

    private:

      string state;

    public:

      void setState(string st);

      Originator creatorMemento()

      {

        return clone();

      }

      restoreMemento(Originator or)

      {

        setState(or.getState);

      }

      

      Originator clone()

      {

        //其实就是拷贝构造一个

      }

    };

    class Caretaker
    {

    private:

      Originator or;

      Originator getOriginator()

      {

        return or;

      }

      void setOriginator(Originator originator)

      {

        or = originator;

      }

    }

    既然可以合并备忘录角色,那么管理员也是可以合并的

    class Originator :public Cloneable

    {

    private:

      Originator* _backup;

      string _state;

    public:

      Originator(const Originator& or)

      {} 

      void setState();

      void creatMemento()

      {

        _bcakup = new Originator(*this);

      }

      void restoreMemento()

      {

        assert(_backup);

        setStat(_backup->getState);

      }

    };

    注:因为clone方式的备忘录可能会因为深浅拷贝问题而复杂,所以clone方式的备忘录适用简单的场景

    ②多状态备忘录

    在Originator中封装多个状态,而Memento则保存一个HashMap 的state

    ③多备份的备忘录

    注:管理员角色封装一的HashMap封装一个备忘录而非备忘状态

    eg

    class Caretaker

    {

    private:

      HashMap<string,Memento> memMap;

    public:

      Memento getMemento(stirng index)

      {}

      void setMemento(string index,Memento me)

      {

        memMap.put(index,me);

      }

    };

    void Test

    {

      Originator or = new Originator();

      Caretaker ca = new Caretaker();
      ca.setMemento("001",or.createMemento());
      ca.setMemento("002",or.createMemento());

      or.restoreMemento(ca.getMemento("001"));

    }

    注:该模式下应当注意备忘录上限,控制内存

    提升:提供权限问题

    class Originator

    {

    private:

      string state;

    public:

      void setState(string st);

      Imemento createMemento()

      {

        return new Memento(state);

      }

      void restoreMemento(Imemento me)

      {

        setState(me.getState());

      }

    private:

      //内置类,实现

      class Memento :public IMemento

      {

      private:

        string state;

        Memento(string st)

        {

          state = st;

        }

        string getState();

        void setState(string st);

      };

    };

    class Imemento

    {

    public: 

      virtual ~Imemento()=0;

    };

    class Caretaker

    {

      Imemento memento;

    public:

      Imemento getMemento()

      {

        return memento;

      }

      void setMemento(Imemento mem)

      {

        memento = mem;

      }

    };

    注:这里的设计方案:双接口设计,一个是业务的正常接口,实现必要的业务逻辑,宽接口;另一个则是空接口,什么方法都没有,目的是提供给子系统外的模块访问,窄接口。窄接口中没有任何操纵数据的方法,所以是相对安全的。

  • 相关阅读:
    Python 第四十九章 css 补充
    Python 第四十八章 css样式
    Python 第四十七章 css介绍
    iOS 流媒体 基本使用 和方法注意
    iOS 展示 gif
    iOS UIImage UIImageView 展示图片 不变形 处理
    UIImageView 获取图片的 宽 高
    iOS tabbar 上面更换任意图
    iOS 屏幕原点坐标 && 导航栏风格的自定义
    iOS NSDateFormatter 不安全线程 处理
  • 原文地址:https://www.cnblogs.com/lang5230/p/5335751.html
Copyright © 2011-2022 走看看