备忘录模式
概念
备忘录模式(Memento Pattern)是一种行为设计模式,用于在不暴露对象内部状态的情况下,捕获并存储对象的当前状态,以便日后可以将对象恢复到存储的状态。备忘录模式可以有效地实现撤销/恢复操作。
组件和职责
组件 | 描述 |
Originator(发起人) | 定义一个创建备忘录和恢复备忘录的接口,记录并还原对象状态。 |
Memento(备忘录) | 存储发起人的状态,提供发起人访问但对其他对象不可见,确保封装性。 |
Caretaker(管理者) | 负责保存备忘录但不修改它的内容,通常通过栈或列表记录状态以支持多步撤销或恢复操作。 |
使用场景
使用场景 | 描述 |
需要保存对象状态 | 需要将对象状态保存到外部存储但不暴露内部实现细节。 |
支持撤销/恢复功能 | 允许用户撤销某些操作并恢复到之前的状态,如文本编辑器、游戏状态管理等。 |
复杂对象状态管理 | 状态的保存和恢复需要被系统有效管理,避免直接操作对象的内部实现。 |
优点与缺点
优点 | 缺点 |
封装性:保持对象的封装性,外部无法访问内部状态。 | 存储开销:保存多个备忘录可能消耗较多资源。 |
撤销/恢复:支持轻松撤销和恢复操作。 | 实现复杂性:设计和管理备忘录存储结构复杂。 |
操作简单:发起人通过接口即可实现状态保存与恢复。 | 过多备忘录:历史记录过多可能影响性能。 |
与其他模式的比较
特性 | 备忘录模式 | 命令模式 |
主要作用 | 保存和恢复对象状态 | 将操作封装为对象,支持撤销和记录。 |
状态管理 | 专注于对象状态的存储和恢复 | 通过执行命令的撤销方法管理状态。 |
操作与状态的分离 | 将状态存储和操作逻辑分开 | 将操作封装为命令对象,与状态解耦。 |
实现代码
C++ 实现
#include <iostream>
#include <string>
#include <vector>
// Memento
class Memento {
private:
std::string state;
public:
Memento(const std::string& s) : state(s) {}
std::string getState() const { return state; }
};
// Originator
class Originator {
private:
std::string state;
public:
void setState(const std::string& s) { state = s; }
std::string getState() const { return state; }
Memento saveToMemento() { return Memento(state); }
void restoreFromMemento(const Memento& memento) { state = memento.getState(); }
};
// Caretaker
class Caretaker {
private:
std::vector<Memento> mementoList;
public:
void addMemento(const Memento& memento) { mementoList.push_back(memento); }
Memento getMemento(size_t index) { return mementoList.at(index); }
};
// Example
int main() {
Originator originator;
Caretaker caretaker;
originator.setState("State1");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State2");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State3");
std::cout << "Current State: " << originator.getState() << std::endl;
originator.restoreFromMemento(caretaker.getMemento(0));
std::cout << "Restored to: " << originator.getState() << std::endl;
return 0;
}
C# 实现
using System;
using System.Collections.Generic;
// Memento
class Memento {
public string State { get; private set; }
public Memento(string state) {
State = state;
}
}
// Originator
class Originator {
public string State { get; set; }
public Memento SaveToMemento() {
return new Memento(State);
}
public void RestoreFromMemento(Memento memento) {
State = memento.State;
}
}
// Caretaker
class Caretaker {
private List<Memento> _mementos = new List<Memento>();
public void AddMemento(Memento memento) {
_mementos.Add(memento);
}
public Memento GetMemento(int index) {
return _mementos[index];
}
}
// Example
class Program {
static void Main() {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.State = "State1";
caretaker.AddMemento(originator.SaveToMemento());
originator.State = "State2";
caretaker.AddMemento(originator.SaveToMemento());
originator.State = "State3";
Console.WriteLine($"Current State: {originator.State}");
originator.RestoreFromMemento(caretaker.GetMemento(0));
Console.WriteLine($"Restored to: {originator.State}");
}
}
类图