学以致用C++设计模式 之 “备忘录模式”
时间:2022-07-23
本文章向大家介绍学以致用C++设计模式 之 “备忘录模式”,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
春花秋月何时了,往事知多少?
往事不堪回首,月如钩。寂寞梧桐深院锁清秋。春花秋月何时了,往事知多少?小楼昨夜又东风,故人不堪回首,月明中。
我记性不好,所以很多事情都要做备忘录,像一些回忆、照片、日常聊天、物件,虽然知道那些时光是回不去了,但是以前还是希望能回得去的。
这个备忘录有个什么优点呢?它有时间戳啊,想回到哪天就回到哪天。它还增删自由啊,当然,改是不允许改了,为了保证回忆的纯净。
我的好兄弟啊钒,总是说我放不下,其实也没啥放不下的,前两周不就放下了嘛,我把以前相关的备忘录全删了,也是该开始新的生活了,一直困在过去,画地为牢,有什么意思呢?
生活如此,程序也是如此,备忘录模式是一个很常用的模式,或者说,备忘录的功能是很多人都需要实现的,也有些人想实现却不知道怎么实现,嫌麻烦。不然我上一篇备忘录,也不至于就那么点访问量有那么高收藏量。
来,我教你实现备忘录。首先要有几个什么元素呢? 首先你要有想存的东西,这不是废话嘛,这个东西要支持存储;其次你得有个容器,也就是管理者(比方说U盘),实现了存、取、查、删等该实现的功能,我的U盘还支持加密呢;最后,就是执行存取操作的人,这个人,他学问也不少,比方说这个U盘啊,是不是加密,是不是只有你一个人能访问是吧,那就又涉及到密保了。
来张图吧,看的直观。
代码实现
#include<iostring>
#include<string> //以此替代结构体,结构体要自己定义
using namespace std;
//备忘录
class Memento{
private:
string State;//状态,建议使用结构体存储
public:
Memento(string value){State = value;}
string get_State(return State;);
}
//发起人
class Originator{
private:
string State; //状态,建议使用结构体存储
public:
string get_state(){return State;}
void set_state(string value){State = value;}
Memento Create_Memento(){return (new Memento(State));} //创建备忘录,将当前需要的信息导入并实例化出一个Memento对象
void set_memento(Memento *memento){State = memento->get_State();} //恢复备忘录
void show(){cout<<State<<endl;} //显示数据
};
//管理者类
class Caretaker{
private:
Memento *memento;
public:
Memento get_Memento(){return memento;} //得到备忘录
}
//主函数
int main()
{
Originator *o = new Originator();
o->set_state("A");
o->show();
Caretaker *c = new Caretaker();
c->memento = o.Create_Memento();//保存状态。有管理类挡在前面,很好的隐藏了备忘录类的实现细节
o->set_state("B"); //更改状态
o->show();
o->set_memento(c->memento); //恢复状态,解释同上
o->show();
}
感悟
如果要加多个备忘录,可以在管理者类中放上容器,自己实现。 被上面那个类中类搞晕了,哈哈哈,难搞啊。
备忘录模式之使用场景
在不破坏封装性的前提下,获取一个对象的状态,并将这个状态保存在类外,这样以后就可以恢复这个状态。
使用场景
- 需要保存数据和恢复数据的相关场景。
- 提供一个可回滚的操作。
- 需要监控的副本场景中。
注意事项
备忘录的生命周期,要主动管理它的生命周期,不使用就删了。 备忘录的性能:不要在频繁建立备份的场景中使用备忘录模式,因为控制不了备忘录建立的数量。
- Ajax jsonp 跨域请求实例
- asp.net动态解析用户控件(UserControl)
- 找到多个与名为“Home”的控制器匹配的类型的解决方案
- 关于sequence问题的紧急处理(r2第26天)
- 使用动态变量进行动态数据比较(r2笔记25天)
- MVC分部视图@Html.Partial
- 基于马尔科夫链的产品评估预测
- MVC 控制器中传递dynamic(对象) 给视图
- 使用copy命令解决LONG类型的困扰(r2第24天)
- MVC 获取路由的 URL 参数值和默认值的集合。
- 用libsvm进行回归预测
- mvc路由配置.html结尾的伪静态
- 【编程基础】Java的接口和抽象类
- 循序渐进调优union相关的sql(r2笔记23天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux 编写Shell脚本
- Linux文件权限与归属、文件的特殊权限、文件的隐藏属性
- Linux文件访问控制列表、su命令与sudo服务
- GPS之 NMEA-0183协议
- Zeppelin 安装与初体验
- Hive 安装与配置
- 如何将SAP Cloud for Customer的扩展字段放置到Embedded Component中
- pthread的使用
- shell程序设计
- SAP CDS view权限控制实现原理介绍
- shell程序设计的流程控制
- SAP CRM数据库表CRMD_SRV_REFOBJ和CRMD_SRV_OSSET
- 堆和栈的区别
- 用ABAP模拟JavaScript的柯里化语言特性(Curry)
- 使用ABAP并发编程解决一个实际应用场景中的性能瓶颈问题