备忘录(Memento)模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
在文字编辑器的示例中,我们可以增加一个可以保存历史快照的字段。编辑器每次执行操作前,存储在 history 中的备忘录栈都会生长。
当用户触发撤销操作时,将从 history 栈中取回最近的备忘录, 并将其传递给编辑器以请求进行回滚。由于编辑器拥有对备忘录的完全访问权限,因此它可以使用从备忘录中获取的数值来替换自身的状态。
代码示例:
package main
import (
"fmt"
)
// 编辑器
type Editor struct {
content string
history []func()
}
func (e *Editor) makeSnapshot() {
currentContent := e.content
restoreFunc := func() { e.content = currentContent }
e.history = append(e.history, restoreFunc)
}
// 写入内容
func (e *Editor) Write(newContent string) {
// 保存当前快照
e.makeSnapshot()
// 写入新内容
e.content = newContent
}
func (e *Editor) Restore() {
historyLen := len(e.history)
restoreFunc := e.history[historyLen-1]
e.history = e.history[:historyLen-1]
restoreFunc()
}
func main() {
e := Editor{}
// 写入内容
e.Write("1. 你好,世界!")
fmt.Println("written:", e.content)
// 写入内容
e.Write("2. 我是axiaoxin!")
fmt.Println("written:", e.content)
// 写入新内容覆盖旧内容
e.Write("3. over!")
fmt.Println("written:", e.content)
// 恢复旧内容
e.Restore()
fmt.Println("restored:", e.content)
// 恢复旧内容
e.Restore()
fmt.Println("restored:", e.content)
// 恢复旧内容
e.Restore()
fmt.Println("restored:", e.content)
}
运行示例代码,输出结果:
written: 1. 你好,世界!
written: 2. 我是axiaoxin!
written: 3. over!
restored: 2. 我是axiaoxin!
restored: 1. 你好,世界!
restored: