解析C#设计模式编程中备忘录模式的运用

作者:Learning hard 时间:2023-06-10 11:40:00 

一、概述

在软件开发中,有时需要保存一个对象的状态,以便于允许用户取消相关操作或者从以往的状态中恢复过来。比如一个文档版本管理系统,可以根据需要将指定文档恢复到之前保存过的任意一个状态。这时就可以通过备忘录模式来实现。

二、备忘录模式

备忘录模式可以在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态。其结构图如下:

解析C#设计模式编程中备忘录模式的运用

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#,备忘录模式
0
投稿

猜你喜欢

  • android panellistview 圆角实现代码

    2022-09-03 17:34:19
  • SpringBoot如何通过devtools实现热部署

    2022-07-23 10:04:10
  • 一篇文章带你深入了解Java线程池

    2021-11-22 21:59:42
  • Java MapStruct解了对象映射的毒

    2022-08-20 11:37:12
  • C#中的HttpWebRequest类用法详解

    2022-11-07 11:41:17
  • C# 如何解析获取Url参数值

    2022-07-03 01:00:52
  • Android studio开发实现计算器功能

    2022-02-12 19:43:05
  • C语言中fchdir()函数和rewinddir()函数的使用详解

    2022-02-08 20:08:08
  • C#使用foreach循环遍历数组完整实例

    2021-12-27 15:10:33
  • mybatis like模糊查询特殊字符报错转义处理方式

    2023-09-02 21:14:54
  • Java计算文本MD5加密值的方法示例

    2023-11-15 13:18:48
  • Android中Spinner(下拉框)控件的使用详解

    2021-08-09 01:46:28
  • Java System类用法实战案例

    2023-04-11 07:28:59
  • 在Java中按值调用和按引用调用

    2021-12-26 20:09:21
  • 详解C#实现在Excel单元格中应用多种字体格式

    2023-01-25 07:58:52
  • Java常见面试题之多线程和高并发详解

    2023-07-24 09:33:51
  • c#(Socket)异步套接字代码示例

    2021-06-28 11:06:03
  • Spring Security保护用户密码常用方法详解

    2023-01-24 17:06:18
  • Java分形绘制山脉模型

    2023-05-10 00:51:29
  • springboot配置项目启动后自动打开浏览器访问项目方式

    2023-10-05 07:33:09
  • asp之家 软件编程 m.aspxhome.com