设计模式 18 备忘录模式

设计模式 18

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

文章目录

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

备忘录模式(Memento Pattern)

1 定义

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

2 结构

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

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

UML 类图

scss 复制代码
+---------------------------------------+      
|  Originator                           |       
+---------------------------------------+     
| - state: String                       |   
| + CreateMemento(): Memento            |  
| + SetMemento(memento: Memento): void  |  
+---------------------------------------+     
        |                          
        |                          
+-----------------------+           +-----------------------+
|   Memento             |           |   Caretaker           |
+-----------------------+           +-----------------------+
| - state: String       |           | - memento: Memento    |
| + GetState(): String  |           +-----------------------+
+-----------------------+     

3 示例代码

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

原发器

csharp 复制代码
// 原发器类
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();
    }
}

备忘录

csharp 复制代码
// 备忘录类
public class Memento
{
    private readonly string _state;

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

    public string GetState()
    {
        return _state;
    }
}

负责人

csharp 复制代码
// 负责人类
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;
    }
}

客户端代码

csharp 复制代码
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());
    }
}

运行结果

plaintext 复制代码
Current Text: Version 3
Restored Text: Version 2
Restored Text: Version 1

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

6 特点

  • 优点:

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

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

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

  • 缺点:

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

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

7 适用场景

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

8 总结

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

相关推荐
Theodore_10227 小时前
7 设计模式原则之合成复用原则
java·开发语言·jvm·设计模式·java-ee·合成复用原则
武子康7 小时前
Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片段
java·sql·设计模式·架构·mybatis·代理模式
博风10 小时前
设计模式:4、命令模式(双重委托)
设计模式·命令模式
捕鲸叉10 小时前
C++适配器模式之可插入适配器的实现模式和方法
开发语言·c++·设计模式
捕鲸叉10 小时前
C++结构型设计模式之适配器模式概述
c++·设计模式·适配器模式
RT_011410 小时前
设计模式之策略模式
java·设计模式·策略模式
lexusv8ls600h14 小时前
微服务设计模式 - 物化视图模式(Materialized View Pattern)
微服务·设计模式·云原生·架构
萨达大14 小时前
23种设计模式-备忘录(Memento)设计模式
java·c++·设计模式·软考·备忘录模式·软件设计师·行为型设计模式
冰零(lane)15 小时前
状态模式之状态机
java·设计模式·状态模式
萨达大17 小时前
23种设计模式-访问者(Visitor)设计模式
java·c++·设计模式·软考·访问者模式·软件设计师·行为型设计模式