1. 什么是备忘录模式?
备忘录模式是一种行为设计模式,它允许在不暴露对象内部状态的情况下,保存和恢复对象的状态。备忘录模式的核心思想是将对象的状态保存到一个备忘录对象中,以便在需要时可以恢复到之前的状态。这种模式通常用于实现撤销操作或历史记录功能。
备忘录模式通常包含三个主要组成部分:发起人(Originator)、备忘录(Memento)和管理者(Caretaker)。
- 发起人(Originator):发起人是需要保存其状态的对象。它负责创建一个备忘录以保存其当前状态,并可以使用备忘录恢复其状态。发起人通常包含一些业务逻辑和状态信息。
- 备忘录(Memento):备忘录用于存储发起人的内部状态。备忘录对象通常是不可变的,以防止外部对象修改其状态。备忘录只提供状态的存储,不提供任何业务逻辑。
- 管理者(Caretaker):管理者负责管理备忘录对象,保存和恢复发起人的状态。管理者不需要了解备忘录的具体内容,只需保存和恢复。它通常维护一个备忘录列表,以便在需要时可以访问。
备忘录模式在软件设计中具有多种优点:
- 封装性:备忘录模式可以在不暴露对象内部状态的情况下保存和恢复状态。发起人可以将其状态封装在备忘录对象中,外部对象无法直接访问或修改这些状态。
- 简化代码:通过将状态管理逻辑分离到备忘录对象中,可以简化发起人的代码。发起人只需关注其业务逻辑,而不必处理状态的保存和恢复。
- 支持撤销操作:备忘录模式可以轻松实现撤销操作,允许用户恢复到之前的状态。这在许多应用程序中都是一个重要的功能,例如文本编辑器、图形编辑器等。
# 备忘录类
class Memento:def __init__(self, state):self.__state = state # 将状态设置为私有属性def get_state(self):return self.__state # 提供访问方法# 发起人类
class TextEditor:def __init__(self):self.text = ""def set_text(self, text):self.text = textprint(f"Current text: '{self.text}'")def save(self):return Memento(self.text)def restore(self, memento):self.text = memento.get_state()print(f"Restored text: '{self.text}'")# 管理者类
class Caretaker:def __init__(self):self.mementos = []def save_memento(self, memento):self.mementos.append(memento)def get_memento(self, index):return self.mementos[index]# 客户端代码
if __name__ == "__main__":def test1():editor = TextEditor()editor.set_text("Hello, World!")memento = editor.save() # 保存状态# 尝试直接访问 memento.__statetry:print(memento.__state) # 这将引发 AttributeErrorexcept AttributeError:print("Cannot access memento state directly!") # 这行会被执行# 正确的方式是使用 get_state 方法print(f"Accessing memento state through method: '{memento.get_state()}'")def test2():editor = TextEditor()caretaker = Caretaker()editor.set_text("Hello, World!")caretaker.save_memento(editor.save()) # 保存状态editor.set_text("Hello, Python!")caretaker.save_memento(editor.save()) # 保存新状态# 恢复状态editor.restore(caretaker.get_memento(0)) # 输出: Restored text: 'Hello, World!'def test3():editor = TextEditor()caretaker = Caretaker()# 设置文本并保存状态editor.set_text("Hello, World!")caretaker.save_memento(editor.save())editor.set_text("Hello, Python!")caretaker.save_memento(editor.save())# 撤销到之前的状态print("\nUndoing last operation:")last_memento = caretaker.get_memento(0) # 获取第一个备忘录editor.restore(last_memento) # 恢复到 'Hello, World!'# 继续撤销操作print("\nUndoing to initial state:")last_memento = caretaker.get_memento(1) # 获取第二个备忘录editor.restore(last_memento) # 恢复到 'Hello, Python!print('test1:')test1()print('\ntest2:')test2()print('\ntest3:')test3()
test1:
Current text: 'Hello, World!'
Cannot access memento state directly!
Accessing memento state through method: 'Hello, World!'test2:
Current text: 'Hello, World!'
Current text: 'Hello, Python!'
Restored text: 'Hello, World!'test3:
Current text: 'Hello, World!'
Current text: 'Hello, Python!'Undoing last operation:
Restored text: 'Hello, World!'Undoing to initial state:
Restored text: 'Hello, Python!'
代码解析:
TextEditor
类是发起人,包含一个text
属性来保存文本内容。set_text
方法用于设置文本并打印当前状态。save
方法创建并返回一个备忘录对象,保存当前文本状态。restore
方法使用备忘录对象恢复文本状态
Memento
类用于存储发起人的状态。在这个例子中,它保存了文本编辑器的文本状态。__state
属性用于保存发起人的内部状态,并通过get_state
方法提供访问。
Caretaker
类负责管理备忘录对象,维护一个mementos
列表来保存多个备忘录。save_memento
方法用于将备忘录对象添加到列表中。get_memento
方法根据索引返回相应的备忘录对象。
- test1:
Memento
类封装了TextEditor
的内部状态。外部对象无法直接访问Memento
的__state
属性,从而保护了发起人的内部状态。 - test2:
TextEditor
类的代码保持简洁,专注于文本的设置和恢复。状态的管理逻辑被转移到Caretaker
类中,从而简化了发起人的代码。 - test3: 用户可以通过
Caretaker
类保存多个备忘录,并在需要时恢复到之前的状态。通过调用restore
方法,用户可以轻松实现撤销操作。