C++设计模式之备忘录模式(Memento)

当我们在实际应用中需要提供撤销机制,当一个对象可能需要再后续操作中恢复其内部状态时,就需要使用备忘录模式。其本质就是对象的序列化和反序列化的过程,支持回滚操作。

作用

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

类视图

实现

typedef struct sysstate; //假设的一个空结构,用来代表系统状态

//还原点
class Memento
{
public:
 Memento(sysstate &statein)
 {
  state = statein;
 }
 sysstate& getstate(){ return state}
private:
 sysstate state;
};

//运行系统
class system
{
public:
 void recovery(Memento* pMem)
 {
  if (pMem)
  {
   state = pMem->getstate();
  }
 }
 Memento* backup()
 {
  return new Memento(state);
 }
private:
 sysstate state;
};

//还原控制器
class recoveryControl
{
public:
 ~recoveryControl()
 {
  map<long,Memento*>::iterator iter;
  for ( iter = m_mementos.begin(); iter != m_mementos.end(); iter++)
  {
   delete iter.second;
  }
 }
 long addRecoveryPoint(Memento* pMem)
 {
  long t = clock();
  m_mementos.instert(pair<long,Memento*>(t, pMem));
  return t;
 }
 Memento* GetRecoveryPoint(long time)
 {
  map<long,Memento*>::iterator iter; 

  iter = m_mementos.find(time); 

  if(iter != m_mementos.end())
   return iter->second;
  return NULL;
 }
 void DelRecoveryPoint(long time)
 {
  Memento* pMem = GetRecoveryPoint(time);
  m_mementos.erase(time);
  delete pMem;
 }
private:
 map<long,Memento*> m_mementos;
};

int main()
{
 system Sys;
 recoveryControl controler;
 //备份系统并存入备份管理器中
 long time1 = controler.addRecoveryPoint(Sys.backup());
 long time2 = controler.addRecoveryPoint(Sys.backup());

 //将系统恢复到time1状态
 Sys.recovery(controler.GetRecoveryPoint(time1));

 //将系统恢复到time2状态
 Sys.recovery(controler.GetRecoveryPoint(time2));

}

应用场景

支持回滚操作的 地方,如游戏存档、事务回滚、程序的撤销和恢复操作等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 设计模式中的备忘录模式解析及相关C++实例应用
  • C++设计模式之备忘录模式
  • C++设计模式之桥接模式(Bridge)
  • C++设计模式之组合模式(Composite)
  • C++设计模式之享元模式(Flyweight)
  • C++设计模式之策略模式(Strategy)
  • C++设计模式之模板方法模式(TemplateMethod)
  • C++设计模式之观察者模式(Observer)
  • C++设计模式之迭代器模式(Iterator)
  • C++设计模式之适配器模式(Adapter)
时间: 2018-04-12

设计模式中的备忘录模式解析及相关C++实例应用

备忘录模式旨在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.在命令模式中,备忘录模式经常还经常被用来维护可以撤销(Undo)操作的状态. 类图: Originator:负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态.Originator可根据需要决定Memento存储Originator的哪些内部状态. Memento:负责存储Originator对象的内部状态,并可防止Origin

C++设计模式之备忘录模式

前言 又到年底了,也静不下心来写代码了,大家都很浮躁:翻出经典的<仙剑奇侠传>玩一会:又要打大BOSS,先存一下档吧.这是我的习惯,在打大BOSS之前,都要先存一下档,要是打赢了,就再存一个档,覆盖之前的:如果打输了,就恢复之前的存档,接着重来.我想大家都是这么玩的吧.哎呀,总是打不过.好了,不玩了,但是,游戏中的那个存档行为却让我很着迷,它是如何实现的呢?带着好奇的心,去百度了一下:哦,原来如此.好吧,开始今天的总结吧--备忘录模式. 备忘录模式 在GOF的<设计模式:可复用面向对象软

C++设计模式之观察者模式(Observer)

观察者模式通常的叫法叫做订阅-发布模式,类似于报刊杂志的订阅,观察者和被观察者就是读者和邮局的关系,读者先要在邮局订阅想要的报刊,当报刊发行时,邮局会将报刊邮寄到读者家里.观察者(Observer)和被观察者(Listener)也是这种关系,Observer将自己attach到Listener中,当Listener触发时Notify所有Observer. 作用 在观察者模式中,被观察者维护观察者对象的集合,当被观察者对象变化时,它会通知观察者.观察者模式主要是用于解决对象之间一对多的关系. 类视

C++设计模式之桥接模式(Bridge)

桥接模式属于先天模式,这里的先天模式就是说一开始就要把结构搭建好,方便后来的扩展,而不是对已经出现的模块和接口进行改进扩展的.桥接的核心在于实体类和操作类之间的聚合关系,这个聚合关系就是我们所说的"桥",不同于装饰.代理和适配器模式的中的聚合关系,桥接不存在两者之间的继承关系,操作类是完全解耦的,而实体类对于操作类也只是弱耦合. 作用 将抽象部份与它的实现部份分离,使它们都可以独立地变化. 类视图 实现 //操作类 class action { public: virtual void

C++设计模式之享元模式(Flyweight)

享元模式顾名思义就是羽量级模式或者蝇级模式,形容体量小的应用,该模式主要的设计目的是为了迎合系统大量相似数据的应用而生,减少用于创建和操作相似的细碎对象所花费的成本.大量的对象会消耗高内存,享元模式给出了一个解决方案,即通过共享对象来减少内存负载. 作用 通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用.通过归类,将对象的属性分为内蕴状态和外蕴状态.要创建具体的享元对象,我们需要创建一个享元工厂来统一管理对象的生成和输出,享元工厂是实现享元模式的关键. 举个例子,享元

C++设计模式之模板方法模式(TemplateMethod)

模板方法模式使用继承来实现模式的功能,在基类使用一个方法来定义算法的各个步骤,这些步骤(方法)的具体实现会放到子类中,通过这样来实现不同算法对象的算法拼合,完成该对象整体算法的实现. 作用 模板方法中定义了具体操作中所使用算法的各个步骤,并将其实现交由子类完成,从而实现多种不同的功能: 类视图 实现 class Lunch { public: Lunch(){} virtual ~Lunch(){} void feed() { cooking(); eating(); cleaning(); }

C++设计模式之组合模式(Composite)

组合模式为了描述分支包含关系,也就是我们说的树形关系,其对象分为枝和叶,每一枝可包含枝和叶,直到全部为叶节点.我们对枝和叶进行行为抽象,可认为枝和叶都是Component,而叶是最小的操作单元,其下不存在枝和叶,而枝作为Composite里面存有其下枝和叶的组件列表. 作用 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性 类视图 实现 #include <iostream> #include <list> #in

C++设计模式之适配器模式(Adapter)

适配器模式顾名思义在于接口的转换,最形象的例子就如两口转三口电源适配器,口子的数量可以理解为参数数量,一如我们调用三个参数的接口,而提供的接口只有两个参数,那么久需要适配器类进行接口的扩展改造,这就是适配器模式存在的最主要意义. 作用 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,使控制范围之外的一个原有对象与某个接口匹配.适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况. 想使用一个已经存在的类,但如果它的接

C++设计模式之策略模式(Strategy)

策略模式将不同算法的逻辑抽象接口封装到一个类中,通过组合和多态结合的方式来进行不同算法具体的实现. 作用 策略模式是一种定义一系列算法的方法,Strategy类层次为Context定义了一系列的可重用的算法或行为, 所有的算法以相同的方式进行调用,减少了算法类之间的耦合 类视图 实现 class Strategy { public: ~Strategy(); virtual void AlgrithmInterface()=0; protected: Strategy(); }; class C

C++设计模式之迭代器模式(Iterator)

迭代器在STL运用广泛,类似容器的迭代已经成为其重要特性,而迭代器模式则是利用迭代器概念进行的抽象运用,迭代器模式运用广泛和有用,因为其能够不考虑数据的存储方式,而是直接面对数据进行迭代,也就是说我们不用考虑集合是数组(或vector).链表.栈还是队列,而是通过统一的接口进行顺序的访问. 作用 迭代器模式提供了一种顺序访问容器中元素的方法,而无需了解器内部的类型和结构,该模式的核心思想将访问和遍历容器对象的功能交给一个外部的迭代器对象,该迭代器定义了访问聚合对象的接口, 类视图 实现 clas

PHP设计模式之迭代器模式Iterator实例分析【对象行为型】

本文实例讲述了PHP设计模式之迭代器模式Iterator.分享给大家供大家参考,具体如下: 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合. 集合不一定是均一的.图形用户界面框架中的 Window 对象可以收集任意数量的控制对象 - Menu.Slider 和 Button.并且,集合的实现可以有多种方式:PHP 数字是一个集合,但也是一个散列表,一个链接列表,一个堆栈以及

PHP设计模式之迭代器(Iterator)模式入门与应用详解

本文实例讲述了PHP设计模式之迭代器(Iterator)模式.分享给大家供大家参考,具体如下: 迭代器有时又称光标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如list或vector)上遍访的接口,设计人员无需关心容器物件的内容,现在呢,各种语言实作Iterator的方式皆不尽同,有些面向对象语言像Java, C#, Python, Delphi都已将Iterator的特性内建语言当中,完美的跟语言整合,我们称之隐式迭代器(implicit iterator),

Java设计模式之迭代器模式_动力节点Java学院整理

定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节. 类型:行为类模式 类图: 如果要问Java中使用最多的一种模式,答案不是单例模式,也不是工厂模式,更不是策略模式,而是迭代器模式,先来看一段代码吧: public static void print(Collection coll){ Iterator it = coll.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out

Android编程设计模式之迭代器模式详解

本文实例讲述了Android编程设计模式之迭代器模式.分享给大家供大家参考,具体如下: 一.介绍 迭代器模式(Iterator Pattern)又称为游标(Cursor)模式,是行为型设计模式之一.迭代器模式算是一个比较古老的设计模式,其源于对容器的访问,比如Java中的List.Map.数组等,我们知道对容器对象的访问必然会涉及遍历算法,我们可以将遍历的方法封装在容器中,或者不提供遍历方法.如果我们将遍历的方法封装到容器中,那么对于容器类来说就承担了过多的功能,容器类不仅要维护自身内部的数据元

Python设计模式之迭代器模式原理与用法实例分析

本文实例讲述了Python设计模式之迭代器模式原理与用法.分享给大家供大家参考,具体如下: 迭代器模式(Iterator Pattern):提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示. 下面是一个迭代器模式的demo: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式--迭代器模式 迭代器模式(Iterator Pattern):提供方法顺序访

php设计模式之迭代器模式实例分析【星际争霸游戏案例】

本文实例讲述了php设计模式之迭代器模式.分享给大家供大家参考,具体如下: 星际的任务关一般会有这样的设定:一开始电脑的农民不采矿,如果战斗打响,或者玩家造出第一个兵,电脑的农民开始采矿. 我们自然会想到把电脑的农民放到一个数组,然后一旦玩家造兵,或者战斗打响,把这个数组循环,让里面的农民采矿. 但问题出来了,由于每个任务的设定会有所不同,我们总希望任务的开发比较方便,而且容易修改(一旦发现bug). 何况有些任务不是农民采矿,而是电脑出兵攻击玩家. 那么过多的固定细节(用数组存放)以及依赖细节

深入理解JavaScript系列(35):设计模式之迭代器模式详解

介绍 迭代器模式(Iterator):提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 迭代器的几个特点是: 1.访问一个聚合对象的内容而无需暴露它的内部表示. 2.为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作. 3.遍历的同时更改迭代器所在的集合结构可能会导致问题(比如C#的foreach里不允许修改item). 正文 一般的迭代,我们至少要有2个方法,hasNext()和Next(),这样才做做到遍历所有对象,我们先给出一个例子: 复

学习JavaScript设计模式之迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. JavaScript中的Array.prototype.forEach 一.jQuery中的迭代器 $.each([1, 2, 3], function(i, n) { console.log("当前下标为:"+ i + " 当前元素为:"+ n ); }); 二.实现自己的迭代器 var each = function(ary, callback) { for(var i

PHP设计模式之迭代器模式

在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素而又不暴露该对象的内部表示,这就是PHP迭代器模式的定义. 适用场景: 访问一个聚合对象的内容而无需暴露它的内部表示 支持对聚合对象的多种遍历 为遍历不同的聚合结构提供一个统一的接口 迭代器模式实例: <?php class ConcreteIterator implements Iterator{ private $position = 0; private $arr; function __construct(array $arr){