设计模式--备忘录模式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;
}
};
注:这里的设计方案:双接口设计,一个是业务的正常接口,实现必要的业务逻辑,宽接口;另一个则是空接口,什么方法都没有,目的是提供给子系统外的模块访问,窄接口。窄接口中没有任何操纵数据的方法,所以是相对安全的。
设计模式--备忘录模式C++实现的更多相关文章
- [转] Android中的设计模式-备忘录模式
转自Android中的设计模式-备忘录模式 定义 备忘录设计模式的定义就是把对象的状态记录和管理委托给外界处理,用以维持自己的封闭性. 比较官方的定义 备忘录模式(Memento Pattern)又叫 ...
- Java设计模式—备忘录模式
个人感觉备忘录模式是一个比较难的设计模式,备忘录模式就是一个对象的备份模式,提供了一种程序数据的备份方法. 定义如下:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以 ...
- JAVA 设计模式 备忘录模式
用途 备忘录模式 (Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 备忘录模式是一种行为型模式. 结构
- [工作中的设计模式]备忘录模式memento
一.模式解析 备忘录对象是一个用来存储另外一个对象内部状态的快照的对象.备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把 ...
- 深入浅出设计模式——备忘录模式(Memento Pattern)
模式动机 为了使软件的使用更加人性化,对于误操作,我们需要提供一种类似“后悔药”的机制,让软件系统可以回到误操作前的状态,因此需要保存用户每一次操作时系统的状态,一旦出现误操作,可以把存储的历史状态取 ...
- IOS设计模式-备忘录模式
内容大纲 如何存储记录 备忘录模式的基本原理 使用备忘录模式 优化存储方案 恢复UIView的状态 1.如何存储记录 在存储记录时,第一步我们需要用一把钥匙去打开一把锁.第二步,当我们打开锁之后就会有 ...
- PHP设计模式——备忘录模式
声明:本系列博客參考资料<大话设计模式>,作者程杰. 备忘录模式又叫做快照模式或Token模式,在不破坏封闭的前提下.捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对 ...
- java设计模式---备忘录模式
一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...
- C++设计模式——备忘录模式
备忘录模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对备忘录模式是这样说的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢 ...
- C#设计模式-备忘录模式
访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而本文要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘 ...
随机推荐
- YYModel源代码阅读--基础知识
这段时间因为工作需要,阅读了YYModel这个开源框架,至于它能做什么,最直白的讲述就是JSON与Model之间的相互转化. 源代码在Github,大家可以自行git clone或者download. ...
- PKU 4334 Trouble(哈希)
原题链接 思路:哈希存入相反数 注意:HDU不支持long long要使用__int64 #include<cstdio> #include<cstring> #define ...
- Mac OS OpenVpN 连接设置(转)
下文介绍Mac OS连接使用OpenVPN方法教程,使用的软件是免费开源的Tunnelblick,当然也有其它连接软件,比如Viscosity,不过这个是付费的,还是前面的用的多. 1.下载安装Tun ...
- SHUOJ - 算法题1 矩阵连乘问题(区间dp)
链接:http://acmoj.shu.edu.cn/problem/24/ 分析:设\(dp[i][j]\)为矩阵\(A[i:j]\)所需的最少乘法次数,则有dp方程:\(dp[i][j]=min\ ...
- 解决日志unicode编码问题
Xcode打印日志里如果有汉字,有时会以Unicode编码形式展示,另需工具转码,降低了开发的效率,未解决这一问题,简便的解决方法是 pod 'HYBUnicodeReadable' 这个第三方库很好 ...
- etcd:从应用场景到实现原理的全方位解读 转自infoq
转自 infoq etcd:从应用场景到实现原理的全方位解读 http://www.infoq.com/cn/articles/etcd-interpretation-application-scen ...
- 原生js 操作dom
1.一些常用的方法 obj.getElementById() 返回带有指定 ID 的元素. obj.getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表(集合/节 ...
- netty7---自定义序列化接口
package com.cn.core; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.util.Ar ...
- 将std::array转换成std::tuple
template<typename Array, std::size_t... Index> decltype(auto) array2tuple_impl(const Array& ...
- iframe的应用量还是这么大
以前查阅资料说iframe已经过时,不建议使用,可是在先进的2018年,你去随便打开一个网站,扔都可以见到iframe的身影,这不禁要发问:iframe的应用量为什么还是这么大? HTML5不再支持使 ...