当前位置: 首页 > article >正文

设计模式 18 备忘录模式

设计模式 18

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 18
    • 备忘录模式(Memento Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 6 特点
      • 7 适用场景
      • 8 总结

备忘录模式(Memento Pattern)

1 定义

备忘录模式的核心思想是将对象的状态保存在一个备忘录对象中,并允许在未来的某个时刻恢复该状态。备忘录模式保证了状态的封装性,外部对象无法直接访问备忘录中的内容,从而保护了原发器对象的内部细节。

2 结构

备忘录模式包含以下角色:

  • 原发器(Originator): 创建备忘录以记录当前状态,并可以使用备忘录恢复先前状态。
  • 备忘录(Memento): 存储原发器的内部状态,备忘录对外部是不可见的,只能由原发器访问。
  • 负责人(Caretaker): 负责存储和管理备忘录,但不会修改或检查备忘录的内容。

UML 类图

+---------------------------------------+      
|  Originator                           |       
+---------------------------------------+     
| - state: String                       |   
| + CreateMemento(): Memento            |  
| + SetMemento(memento: Memento): void  |  
+---------------------------------------+     
        |                          
        |                          
+-----------------------+           +-----------------------+
|   Memento             |           |   Caretaker           |
+-----------------------+           +-----------------------+
| - state: String       |           | - memento: Memento    |
| + GetState(): String  |           +-----------------------+
+-----------------------+     

3 示例代码

假设我们要实现一个简单的文本编辑器,它能够保存文本的状态,并在需要时撤销或恢复状态。

原发器

// 原发器类
public class TextEditor
{
    private string _text;

    public void SetText(string text)
    {
        _text = text;
    }

    public string GetText()
    {
        return _text;
    }

    public Memento CreateMemento()
    {
        return new Memento(_text);
    }

    public void RestoreMemento(Memento memento)
    {
        _text = memento.GetState();
    }
}

备忘录

// 备忘录类
public class Memento
{
    private readonly string _state;

    public Memento(string state)
    {
        _state = state;
    }

    public string GetState()
    {
        return _state;
    }
}

负责人

// 负责人类
public class Caretaker
{
    private readonly Stack<Memento> _mementos = new Stack<Memento>();

    public void SaveMemento(Memento memento)
    {
        _mementos.Push(memento);
    }

    public Memento GetMemento()
    {
        if (_mementos.Count > 0)
        {
            return _mementos.Pop();
        }
        return null;
    }
}

客户端代码

class Program
{
    static void Main(string[] args)
    {
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();

        editor.SetText("Version 1");
        caretaker.SaveMemento(editor.CreateMemento());

        editor.SetText("Version 2");
        caretaker.SaveMemento(editor.CreateMemento());

        editor.SetText("Version 3");
        Console.WriteLine("Current Text: " + editor.GetText());

        editor.RestoreMemento(caretaker.GetMemento());
        Console.WriteLine("Restored Text: " + editor.GetText());

        editor.RestoreMemento(caretaker.GetMemento());
        Console.WriteLine("Restored Text: " + editor.GetText());
    }
}

运行结果

Current Text: Version 3
Restored Text: Version 2
Restored Text: Version 1

在这个例子中,TextEditor 是原发器,负责创建和恢复文本的状态;Memento 是备忘录,保存文本的状态;Caretaker 是负责人,管理备忘录的存储和恢复。在运行过程中,我们保存了多个文本状态,并通过恢复操作撤销了修改,返回到之前的状态。

6 特点

  • 优点:

    • 封装性: 备忘录模式保证了原发器状态的封装性,外部对象无法直接访问备忘录的内容。

    • 状态恢复: 允许对象恢复到之前的状态,提供了实现“撤销/恢复”功能的简单方法。

    • 简化复杂性: 通过将状态的存储和恢复职责分离到不同的类中,简化了复杂系统的管理。

  • 缺点:

    • 开销大: 如果原发器的状态占用大量资源(如内存),备忘录模式可能会导致开销较大,尤其是在频繁保存和恢复状态时。

    • 管理复杂: 如果备忘录数量众多,管理这些备忘录可能变得复杂,尤其是在涉及多线程操作时。

7 适用场景

  • 实现撤销/恢复功能: 当需要实现“撤销/恢复”操作时,备忘录模式非常适用。
  • 需要记录历史状态: 在需要保存和恢复对象的多个历史状态的场景中,可以使用备忘录模式。
  • 简化复杂对象的状态管理: 在复杂对象状态变化频繁且需要保证状态一致性的情况下,备忘录模式提供了一种有效的管理方式。

8 总结

备忘录模式通过保存对象的状态,提供了恢复该状态的机制。它通过封装状态,确保了对象内部细节的保护,同时又允许状态的恢复。该模式非常适合用于实现“撤销/恢复”功能,并在需要管理复杂状态变更的场景中提供了很好的解决方案。


http://www.kler.cn/news/290176.html

相关文章:

  • LeetCode的高频SQL50题(基础版)学习笔记
  • 惠中科技RDS自清洁膜层:光伏领域的绿色革命
  • Spark MLlib模型训练—回归算法 Survival Regression
  • 【Selenium】Selenium运行时报cannot find Chrome binary错误的解决办吧
  • linux之网络子系统-MAC帧、数据报、段 的头部信息
  • 【C++】如何解决“pointer to incomplete class type is not allowed”。
  • 一篇文章讲清楚什么是Spring AOP
  • 从汇编角度分析C语言中的局部变量是如何产生的
  • pikachu文件包含漏洞靶场通关攻略
  • 运维管理体系及其实践要点:为高效运维保驾护航
  • zabbix通过OMSA监控Dell服务器_zabbix dell http
  • 为什么我会有使用gradle,需要花长时间去下载依赖?使用maven就不会有这种感受?
  • c++ websocket简单讲解
  • 大势智慧携“实景三维+AI”信创产品体系亮相2024中国地理信息产业大会
  • 详解 HTTPS 与 TLS证书链校验
  • 避坑之:深信服AC跨三层取MAC(核心交换机是锐捷S7808C_RGOS 11.0(4)B2P1)
  • 实验室ICPR 2024论文分享┆DS MYOLO:一种基于状态空间模型的驾驶场景可靠目标检测器
  • Edge资源占用优化:调整浏览器设置与关闭自动更新检查
  • 工业主板在轨道交通中的应用特点
  • 【网络】P2P打洞原理
  • 专项练习-数据思维-49题
  • PostgreSQL技术内幕4:PostgreSQL存储引擎内存管理
  • 使用udp进行通信
  • 视频结构化从入门到精通——行为分析类应用
  • IEEE PDF eXpress 报错解决 Error in converting file + font not embedded
  • 海康二次开发学习笔记9-通讯触发及模块列表获取
  • LLM手撕
  • JS笔记
  • js逆向——RSA实战案例讲解
  • UART串口通信——FPGA学习笔记9