解析C#设计模式编程中备忘录模式的运用
作者:Learning hard 发布时间:2023-06-10 11:40:00
一、概述
在软件开发中,有时需要保存一个对象的状态,以便于允许用户取消相关操作或者从以往的状态中恢复过来。比如一个文档版本管理系统,可以根据需要将指定文档恢复到之前保存过的任意一个状态。这时就可以通过备忘录模式来实现。
二、备忘录模式
备忘录模式可以在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态。其结构图如下:
Memento用于保存Originator对象的内部状态。
Originator创建Memento,并根据需要决定需要在Memento中保存那些状态,同时还能从Memento中恢复内部状态。
Caretaker负责保存Memento对象,但不对Memento对象进行任何操作。
备忘录模式用来保存与对象有关的数据,这样可以在将来对对象进行复原。例如在绘图程序中需要保存对象的颜色尺寸等。
三、示例
我们我们就以文档版本管理系统为例来介绍备忘录模式。
首先定义Originator,在这里就是文档本身。
public class Document
{
public string Content { get; set; }
public DocumentVersion CreateMemento()
{
return new DocumentVersion( Content);
}
public void SetMemento(DocumentVersion documentVersion)
{
Content = documentVersion.Content;
}
}
接着定义Memento。
public class DocumentVersion
{
public string Content { get; set; }
public DocumentVersion(string content)
{
Content = content;
}
}
最后定义Caretaker,通过一个Dictionary容器保存Memento。
public class Caretaker
{
private Dictionary<int, DocumentVersion> _mementoList = new Dictionary<int, DocumentVersion>();
public DocumentVersion GetDocumentVersion(int versionID)
{
return _mementoList[versionID];
}
public void AddDocumentVersion(DocumentVersion documentVersion)
{
int maxVersionID = _mementoList.Keys.Count == 0 ? 0: _mementoList.Keys.Max();
_mementoList.Add(maxVersionID + 1, documentVersion);
}
}
四、备忘录模式的适用场景
在以下情况下可以考虑使用备忘录模式:
如果系统需要提供回滚操作时,使用备忘录模式非常合适。例如文本编辑器的Ctrl+Z撤销操作的实现,数据库中事务操作。
五、备忘录模式的优缺点
备忘录模式具有以下优点:
如果某个操作错误地破坏了数据的完整性,此时可以使用备忘录模式将数据恢复成原来正确的数据。
备份的状态数据保存在发起人角色之外,这样发起人就不需要对各个备份的状态进行管理。而是由备忘录角色进行管理,而备忘录角色又是由管理者角色管理,符合单一职责原则。
当然,备忘录模式也存在一定的缺点:
在实际的系统中,可能需要维护多个备份,需要额外的资源,这样对资源的消耗比较严重。
六、总结
备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原来状态时,再从备忘录对象中进行获取,在实际开发过程也应用到这点,例如数据库中的事务处理。


猜你喜欢
- 本文实例讲述了C#使用委托实现的快速排序算法。分享给大家供大家参考。具体如下:class QuickSort { private dele
- 本文实例为大家分享了Android创建发送和接收短信应用的简单实现过程,供大家参考,具体内容如下一、接收短信项目的结构如下:一个简单的接收和
- Activity栈主要用于管理Activity的切换。当使用Intent跳转至某个目标Activity,需要根据目标Activity的加载模
- MybatisPlus分页排序查询字段带有下划线如果使用MybatisPlus的自动转驼峰命名法,分页排序查询的字段带有下划线时,会出问题。
- java掩码 private static String nameMask(String name) throws Exception {
- foreach拼接字符串查询无数据返回Mybatis-plus xml使用foreach遍历查询条件,填充IN函数时,查询不到数据入参 Li
- 一、相关知识SearchView控件:以下是几个简单网址:SearchView简单用法:Android搜索框(SearchView)的功能和
- 1:Xxtea支持中文;2:支持JS和C#加解密之间的互转;一:C#部分class XXTEA2 {
- 杂语:看了很多程序猿都有写博客的习惯,看来我也得练练,不管写的好不好了,学到点什么体会就写写吧。内容解说:这几天开始学游戏地图制作,今天小小
- 我们都知道在一些特殊的场景,我们需采用特殊的编码格式,如:UTF-8,但是系统默认的编码为ISO-8859-1那么我们就需要将编码转换为我们
- 目录1,基本介绍2,HttpURLConnection实现3.HttpClient实现4.Spring的RestTemplate1,基本介绍
- 1. 去官方下载log4j 2,导入jar包,基本上你只需要导入下面两个jar包就可以了(xx是乱七八糟的版本号):log4j-core-x
- Java排序 - DualPivotQuicksort这里描述 leftmost = true 的情况,也就是会从数组的开始一直排序到数组的
- 最近项目上要实现语音搜索功能,界面样式要模仿一下UC浏览器的样式,UC浏览器中有一个控件,会随着声音大小浮动,然后寻思偷个懒,百
- 工厂方法模式简述与简单工厂模式基本相同,只是工厂是一个抽象的,需要有具体的工厂去实现它,然后利用这个工厂生产产品,之所以出现这个模式是因为,
- @RequestBody不能class类型匹配在首次第一次尝试使用@RequestBody注解开始加载字符串使用post提交(貌似只能pos
- 本文基于jdk1.8进行分析关于HashMap的简介,可以参考这篇文章https://www.jb51.net/article/154177
- 传统“长轮询”实现Web端即时通讯的问题WebSocket出现之前,Web端为了实现即时通讯,所用的技术都是Ajax轮询(polling)。
- 本文实例讲述了C#多线程处理多个队列数据的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.
- Java中 * 主要有JDK和CGLIB两种方式。区别主要是jdk是代理接口,而cglib是代理类。优点:这种方式已经解决我们前面所有日记