备忘录模式(Memento Pattern)是一种行为设计模式,允许在不破坏对象封装性的前提下捕获并保存对象的内部状态,以便后续可以恢复到该状态。该模式适用于需要实现撤销操作、历史记录或快照功能的场景。
模式结构
备忘录模式包含三个核心角色:
-
Originator(发起人)
需要保存和恢复状态的对象。负责创建备忘录(保存当前状态)和从备忘录恢复状态。
-
Memento(备忘录)
存储 Originator 的内部状态的对象。备忘录的设计需确保只能由 Originator 读写其内容,其他对象无法直接访问。
-
Caretaker(管理者)
负责保存和管理备忘录的历史记录。它不会修改备忘录内容,仅负责存储和传递。
.NET Core 示例:文章编辑器撤销功能
场景描述
实现一个简单的文章编辑器,支持保存当前内容状态,并能通过撤销操作恢复到之前的某个状态。
代码实现
- 定义 Memento(备忘录)
// 备忘录类,保存文章内容
public class ArticleMemento
{
public string Content { get; }
public ArticleMemento(string content)
{
Content = content;
}
}
- 定义 Originator(发起人)
// 文章类(需要保存和恢复状态的对象)
public class Article
{
public string Content { get; set; }
// 创建备忘录(保存当前状态)
public ArticleMemento Save()
{
return new ArticleMemento(Content);
}
// 从备忘录恢复状态
public void Restore(ArticleMemento memento)
{
Content = memento.Content;
}
}
- 定义 Caretaker(管理者)
// 历史记录管理器
public class HistoryManager
{
private readonly Stack<ArticleMemento> _history = new Stack<ArticleMemento>();
// 保存状态
public void SaveState(ArticleMemento memento)
{
_history.Push(memento);
}
// 撤销操作(恢复上一个状态)
public ArticleMemento Undo()
{
if (_history.Count > 0)
{
// 弹出最新保存的备忘录
return _history.Pop();
}
return null;
}
}
- 客户端代码
class Program
{
static void Main()
{
var article = new Article { Content = "First Version" };
var history = new HistoryManager();
// 保存初始状态
history.SaveState(article.Save());
// 修改内容并保存新状态
article.Content = "Second Version";
history.SaveState(article.Save());
// 再次修改内容
article.Content = "Third Version";
Console.WriteLine($"Current Content: {article.Content}"); // 输出 "Third Version"
// 执行一次撤销
var previousState = history.Undo();
if (previousState != null)
{
article.Restore(previousState);
Console.WriteLine($"After Undo: {article.Content}"); // 输出 "Second Version"
}
// 再次撤销
previousState = history.Undo();
if (previousState != null)
{
article.Restore(previousState);
Console.WriteLine($"After Undo: {article.Content}"); // 输出 "First Version"
}
}
}
关键点解释
- 封装性保护:通过
ArticleMemento
类隔离了状态的保存和恢复逻辑,外部无法直接修改备忘录内容。 - 历史管理:
HistoryManager
使用栈(Stack)保存状态,实现后进先出(LIFO)的撤销逻辑。 - 状态恢复:通过
Restore
方法,Article
可以灵活回退到任意历史状态。
优缺点分析
优点:
- 提供可回溯的状态恢复机制,支持撤销/重做。
- 严格封装 Originator 的内部状态,确保数据安全。
缺点:
- 频繁保存状态可能导致内存消耗增加。
- 需要合理设计备忘录存储策略(如限制历史记录数量)。
应用场景
- 文本编辑器、绘图软件的撤销/重做功能。
- 游戏存档/读档系统。
- 事务回滚(如数据库操作)。
通过备忘录模式,可以优雅地实现对象状态的保存与恢复机制,同时保持代码的清晰和可维护性。