模式简介
备忘录模式是一种行为型设计模式,用于对一个对象的状态进行保存和回溯。
常见的应用场景:文本编辑器的撤销功能、图形设计工具的历史记录、数据库事务管理、游戏状态管理、配置管理、日历应用的日程记录和命令模式的辅助等。
备忘录模式(Memento Pattern)是一种行为设计模式,它允许对象在不暴露其内部状态的情况下捕获和恢复其状态。该模式通常用于实现撤销机制。
模式结构
备忘录模式涉及以下几个角色:
-
发起人(Originator): 负责创建一个包含当前状态的备忘录对象,并可以使用备忘录对象恢复其状态。
-
备忘录(Memento): 用于存储发起人对象的内部状态。备忘录对象提供一种机制,允许发起人将其状态恢复到先前的状态。
-
管理者(Caretaker): 负责保存备忘录对象。管理者可以保存多个备忘录对象,但通常仅在需要的情况下保存最新的状态。
工作原理
-
创建备忘录: 发起人创建一个备忘录对象,并将其状态设置为当前状态。
-
存储备忘录: 管理者将备忘录对象保存起来。通常,管理者保存一个备忘录对象,但也可以保存多个以实现多次撤销的功能。
-
恢复状态: 当需要恢复到先前的状态时,发起人从管理者那里获取相应的备忘录对象,并将其状态恢复。
代码示例(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则是在原有字符串基础上直接修改,感兴趣的话可以在网上查阅一下二者更具体的区别,这里就不赘述了。
如果这篇文章对你有帮助,请给作者点个赞吧!