Memento Pattern(备忘录模式、存档点模式)

模式简介

       备忘录模式是一种行为型设计模式,用于对一个对象的状态进行保存和回溯。

       常见的应用场景:文本编辑器的撤销功能、图形设计工具的历史记录、数据库事务管理、游戏状态管理、配置管理、日历应用的日程记录和命令模式的辅助等。

备忘录模式(Memento Pattern)是一种行为设计模式,它允许对象在不暴露其内部状态的情况下捕获和恢复其状态。该模式通常用于实现撤销机制。

模式结构

备忘录模式涉及以下几个角色:

  1. 发起人(Originator): 负责创建一个包含当前状态的备忘录对象,并可以使用备忘录对象恢复其状态。

  2. 备忘录(Memento): 用于存储发起人对象的内部状态。备忘录对象提供一种机制,允许发起人将其状态恢复到先前的状态。

  3. 管理者(Caretaker): 负责保存备忘录对象。管理者可以保存多个备忘录对象,但通常仅在需要的情况下保存最新的状态。

工作原理

  1. 创建备忘录: 发起人创建一个备忘录对象,并将其状态设置为当前状态。

  2. 存储备忘录: 管理者将备忘录对象保存起来。通常,管理者保存一个备忘录对象,但也可以保存多个以实现多次撤销的功能。

  3. 恢复状态: 当需要恢复到先前的状态时,发起人从管理者那里获取相应的备忘录对象,并将其状态恢复。

代码示例(C#)

提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。

文本备忘录对象:TextMemento.cs


using System.Text;

namespace MementoPattern;

// 文本备忘录对象
class TextMemento
{
    // 文本内容
    public string text { get; private set; }

    public TextMemento(StringBuilder text)
    {
        this.text = text.ToString();
    }
}

备忘录对象管理器:MementoManager.cs


using System.Text;

namespace MementoPattern;

// 文本备忘录对象管理器
class MementoManager
{
    // 文本备忘录对象集合
    private Stack<TextMemento> mementos;

    public MementoManager()
    {
        mementos = new Stack<TextMemento>();
    }

    // 保存当前文本状态
    public void SaveState(StringBuilder text)
    {
        mementos.Push(new TextMemento(text));
    }

    // 回溯到上一个文本状态
    public void BackToPreState(StringBuilder text)
    {
        if (mementos.Count > 0)
        {
            text.Clear();
            text.Append(mementos.Pop().text);
        }
    }
}

文本编辑器:TextEditor.cs


using System.Text;

namespace MementoPattern;

// 文本编辑器
class TextEditor
{
    private MementoManager manager; // 文本备忘录对象管理器

    public TextEditor()
    {
        manager = new MementoManager();
    }

    // 保存
    public void Save(StringBuilder text)
    {
        manager.SaveState(text);
    }

    // 撤销
    public void Undo(StringBuilder text)
    {
        manager.BackToPreState(text);
    }
}

测试代码:Program.cs

// ************* 21.备忘录模式测试 **************
using System.Text;
using MementoPattern;

// 创建实例
TextEditor textEditor = new TextEditor();
StringBuilder text = new StringBuilder("Hello world!");

// 保存文本并输出文本
textEditor.Save(text);
Console.WriteLine(text);

// 向文本添加内容并输出文本
text.Append(" I am Jack.");
Console.WriteLine(text);

// 撤销文本操作并输出文本
textEditor.Undo(text);
Console.WriteLine(text);

代码解说

       上述代码简单模拟了文本编辑器保存和撤销的功能。文本编辑器提供保存和撤销功能接口,保存功能会将当前文本的内容封装为一个文本备忘录对象,然后在备忘录对象管理器中入栈管理,撤销功能则是让备忘录对象管理器完成一次文本备忘录对象的出栈,并解析读取文本备忘录对象的文本内容,赋值给可变的文本对象。

       细心的小伙伴应该注意到了上面的StringBuilder,这个类是官方提供的用于实现可变字符串需求的,虽然string类型从外部看来也可变,但是它实际上是通过字符串拼接然后返回新的字符串对象来完成“可变”的,而StringBuilder则是在原有字符串基础上直接修改,感兴趣的话可以在网上查阅一下二者更具体的区别,这里就不赘述了。

如果这篇文章对你有帮助,请给作者点个赞吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值