定义:
Without violating encapsulation,capture and externalize an object's internal state so that the object can be restored to this state later.(在不破坏封装性的前提下,捕获一个对象的内部状 态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。)
备忘录模式通用类图
备忘录设计模式的核心思想是封装状态与隔离访问。它将对象的状态信息封装在备忘录对象中,对象本身负责创建和使用备忘录,而其他对象不能直接访问备忘录的内容,从而保证了对象状态的封装性。同时,通过引入负责人对象来管理备忘录,实现了状态的保存和恢复操作,使得系统可以在需要时轻松回溯到对象的历史状态。
角色:
备忘录模式包含以下几个核心角色:
1、原发器(Originator)
原发器是需要保存和恢复状态的对象。它负责创建备忘录对象,将自身的状态信息存储到备忘录中;同时,也可以使用备忘录对象来恢复自身的状态。原发器是备忘录内容的创建者和使用者。
2、备忘录(Memento)
备忘录用于存储原发器的内部状态。它包含了原发器在某一时刻的状态信息,并且对外部对象隐藏这些状态的具体细节,保证状态的安全性和封装性。备忘录对象通常只提供有限的接口,仅允许原发器访问其内部状态。
3、负责人(Caretaker)
负责人负责管理备忘录对象。它可以保存、获取备忘录,但不直接访问备忘录的内容。负责人只知道备忘录的生命周期管理,例如何时创建备忘录、何时保存备忘录以及何时将备忘录提供给原发器进行状态恢复。
代码示例:
在文本编辑器中,用户输入文本、删除文本等操作会改变文本的内容,使用备忘录模式实现文本编辑的撤销功能。
// 备忘录类,存储文本内容
public class TextMemento {
private String text;
public TextMemento(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
// 原发器类,文本编辑器
public class TextEditor {
private String text;
public TextEditor() {
this.text = "";
}
// 输入文本
public void inputText(String newText) {
text += newText;
}
// 删除文本
public void deleteText(int length) {
if (text.length() >= length) {
text = text.substring(0, text.length() - length);
}
}
// 创建备忘录
public TextMemento createMemento() {
return new TextMemento(text);
}
// 恢复状态
public void restoreMemento(TextMemento memento) {
this.text = memento.getText();
}
public void displayText() {
System.out.println("当前文本内容: " + text);
}
}
// 负责人类,管理备忘录
public class TextCaretaker {
private TextMemento memento;
public TextMemento getMemento() {
return memento;
}
public void setMemento(TextMemento memento) {
this.memento = memento;
}
}
// 客户端代码
public class TextEditorClient {
public static void main(String[] args) {
TextEditor textEditor = new TextEditor();
TextCaretaker caretaker = new TextCaretaker();
System.out.println("文本编辑器初始状态:");
textEditor.displayText();
// 输入文本并保存备忘录
textEditor.inputText("Hello, ");
caretaker.setMemento(textEditor.createMemento());
textEditor.inputText("World!");
System.out.println("\n输入文本后,当前状态:");
textEditor.displayText();
// 删除部分文本
textEditor.deleteText(6);
System.out.println("\n删除文本后,当前状态:");
textEditor.displayText();
// 撤销操作,恢复到之前的状态
textEditor.restoreMemento(caretaker.getMemento());
System.out.println("\n撤销操作后,恢复到之前的状态:");
textEditor.displayText();
}
}
优点 :
1、实现状态管理的灵活性:备忘录模式使得对象的状态保存和恢复操作更加灵活,可以在任意时刻保存对象的状态,并在需要时恢复,方便实现撤销、重做等功能。
2、保证状态的封装性:备忘录模式将对象的状态信息封装在备忘录中,外部对象无法直接访问备忘录的内容,保护了对象状态的完整性和安全性,符合面向对象的封装原则。
3、提高代码的可维护性:通过将状态管理逻辑从对象本身分离出来,使得代码结构更加清晰,当需要修改状态管理的逻辑时,只需要修改备忘录、负责人相关的代码,而不影响对象的其他功能,提高了代码的可维护性。
缺点:
1、资源消耗问题:如果需要保存的对象状态信息过多,或者频繁地创建和保存备忘录,可能会占用大量的内存资源,影响系统的性能。在这种情况下,需要考虑对备忘录进行优化,如采用增量存储、定期清理旧的备忘录等策略。
2、增加系统复杂度:备忘录模式引入了备忘录和负责人等额外的类和对象,增加了系统的类数量和代码复杂度。对于简单的状态管理需求,使用备忘录模式可能会显得过于繁琐,增加不必要的开发成本。
使用场景:
(一)需要实现撤销和恢复功能
当系统需要支持操作的撤销和恢复功能时,备忘录模式是一个理想的选择。例如,文本编辑器中的撤销 / 重做、图形绘制软件中的操作回溯、游戏中的存档与读档等场景,都可以使用备忘录模式来保存和恢复对象的状态。
(二)需要保存对象的历史状态
在某些业务场景中,需要记录对象的历史状态信息,以便进行数据分析、审计或展示。备忘录模式可以将对象的状态按时间顺序保存下来,方便后续查看和恢复。例如,财务系统中记录账户的资金变动历史、版本控制系统中保存文件的不同版本状态等。
(三)需要保护对象状态的封装性
备忘录模式通过将对象状态封装在备忘录中,并且限制外部对象对备忘录的访问,确保了对象状态的安全性和封装性。当不希望外部对象直接访问和修改对象的内部状态时,可以使用备忘录模式来管理状态。
备忘录设计模式通过巧妙地封装和管理对象的状态,为实现对象状态的保存与恢复提供了一种优雅且高效的解决方案。它在支持撤销重做功能、记录历史状态以及保护状态封装性等方面具有显著优势,广泛应用于各类软件系统中。然而,在使用备忘录模式时,也需要注意资源消耗和系统复杂度的问题,根据实际需求合理运用该模式。掌握备忘录设计模式,能够让我们在面对对象状态管理的需求时,编写出更加灵活、可靠的代码。