备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便将来恢复对象到该状态。备忘录模式主要涉及以下几个角色:
-
发起人(Originator):记录当前的内部状态,提供设置内部状态的方法,以及创建和恢复备忘录的方法。
-
备忘录(Memento):存储发起人对象的内部状态。备忘录由发起人对象创建,但只能由备忘录管理器读取。
-
备忘录管理器(Caretaker):负责保存和恢复备忘录,但不能直接访问和修改发起人对象的内部状态。
下面是一个使用Go语言实现的备忘录模式示例: 好的,我们来用一个更复杂的示例重新解释一下备忘录模式。这次我们将创建一个简单的文字编辑器,用于演示如何使用备忘录模式实现撤销/重做功能。
// Originator 发起人
type Editor struct {
content string
}
func (e *Editor) SetContent(content string) {
e.content = content
}
func (e *Editor) GetContent() string {
return e.content
}
func (e *Editor) CreateMemento() *Memento {
return &Memento{content: e.content}
}
func (e *Editor) RestoreMemento(m *Memento) {
e.content = m.GetContent()
}
// Memento 备忘录
type Memento struct {
content string
}
func (m *Memento) GetContent() string {
return m.content
}
// CareTaker 备忘录管理器
type History struct {
mementos []*Memento
current int
}
func (h *History) Backup(m *Memento) {
h.mementos = append(h.mementos, m)
h.current++
}
func (h *History) Undo() *Memento {
if h.current > 0 {
h.current--
}
if h.current >= 1 {
return h.mementos[h.current-1]
}
return nil
}
func (h *History) Redo() *Memento {
if h.current < len(h.mementos) {
it := h.mementos[h.current]
h.current++
return it
}
return nil
}
// 使用示例
func main() {
editor := &Editor{content: "Initial content"}
history := &History{}
// 进行一些编辑操作并保存备忘录
editor.SetContent("First edit")
history.Backup(editor.CreateMemento())
editor.SetContent("Second edit")
history.Backup(editor.CreateMemento())
editor.SetContent("Third edit")
history.Backup(editor.CreateMemento())
// 撤销操作
m := history.Undo()
editor.RestoreMemento(m)
fmt.Println("After undo:", editor.GetContent()) // Output: After undo: Second edit
// 重做操作
m = history.Redo()
editor.RestoreMemento(m)
fmt.Println("After redo:", editor.GetContent()) // Output: After redo: Third edit
}在这个示例中:
-
Editor是发起人角色,它负责维护文本内容的状态,并提供设置/获取内容、创建和恢复备忘录的方法。 -
Memento是备忘录角色,它存储文本内容的状态。 -
History是备忘录管理器角色,它负责保存、撤销和重做编辑操作。
在main函数中,我们首先创建一个Editor对象和一个History对象。然后,我们进行一些编辑操作,每次编辑后都会创建一个Memento对象,并将其保存在History对象中。接着,我们可以通过调用Undo方法来撤销上一步的操作,或者通过调用Redo方法来重做之前撤销的操作。
备忘录模式的关键点在于:
- 发起人对象(
Editor)负责创建和恢复备忘录(Memento),但不能直接访问备忘录的内部状态。 - 备忘录对象(
Memento)只存储发起人对象的内部状态,不提供任何修改状态的方法。 - 备忘录管理器对象(
History)负责保存、管理和提供访问备忘录的方法,但不能直接访问发起人对象的内部状态。
通过这种方式,备忘录模式实现了对象状态的封装和保护,同时也提供了一种可靠的机制来保存和恢复对象的状态。这种模式在需要记录对象状态历史的场景中非常有用,如撤销/重做操作、事务管理、版本控制等。