备忘录模式(Memento Pattern)是一种行为设计模式,用于在不破坏封装的前提下保存和恢复对象的内部状态。在Golang中,虽然没有类和访问修饰符等传统面向对象语言的特性,但通过结构体、接口和闭包等机制,依然可以优雅地实现备忘录模式。
备忘录模式通常包含三个核心角色:
在Go中,我们通过结构体表示这些角色,利用包级私有字段控制状态的可见性,从而实现封装。
下面是一个典型的Go实现方式:
package main import "fmt" // Memento 定义备忘录接口,仅暴露必要的方法 type Memento interface { getState() string } // originatorState 是发起人内部状态(包内私有) type originatorState struct { state string } // Originator 发起人结构体 type Originator struct { state string } func (o *Originator) SetState(state string) { o.state = state fmt.Printf("状态设置为: %s\n", state) } func (o *Originator) SaveToMemento() Memento { return &originatorState{state: o.state} } func (o *Originator) RestoreFromMemento(m Memento) { if m != nil { o.state = m.getState() fmt.Printf("状态恢复为: %s\n", o.state) } } // 实现 Memento 接口 func (s *originatorState) getState() string { return s.state } // Caretaker 管理者,持有备忘录列表 type Caretaker struct { mementos []Memento } func (c *Caretaker) Add(m Memento) { c.mementos = append(c.mementos, m) } func (c *Caretaker) Get(index int) Memento { if index >= 0 && index < len(c.mementos) { return c.mementos[index] } return nil }
使用示例:
func main() {
originator := &Originator{}
caretaker := &Caretaker{}
originator.SetState("状态1")
caretaker.Add(originator.SaveToMemento())
originator.SetState("状态2")
caretaker.Add(originator.SaveToMemento())
originator.SetState("状态3")
originator.RestoreFromMemento(caretaker.Get(1)) // 恢复到状态2
}
Go的闭包能力可以进一步增强封装性。我们可以将状态完全隐藏在函数内部,仅通过返回的函数操作状态。
func NewOriginator() (*OriginatorClosure, func() map[string]interface{}, func(map[string]interface{})) {
state := make(map[string]interface{})
save := func() map[string]interface{} {
snapshot := make(map[string]interface{})
for k, v := range state {
snapshot[k] = v
}
return snapshot
}
restore := func(memento map[string]interface{}) {
state = make(map[string]interface{})
for k, v := range memento {
state[k] = v
}
fmt.Println("状态已恢复")
}
return &OriginatorClosure{setState: func(k string, v interface{}) {
state[k] = v
fmt.Printf("设置 %s = %v\n", k, v)
}}, save, restore
}
type OriginatorClosure struct {
setState func(string, interface{})
}
这种方式更适合需要高度封装或函数式风格的场景。
备忘录模式适用于以下情况:
注意性能开销:频繁保存完整状态可能导致内存增长过快,可结合增量保存或最大快照数限制优化。
基本上就这些。Go虽无传统OOP语法支持,但通过接口隔离、包级私有和闭包,仍能清晰实现备忘录模式的核心意图——安全地保存和恢复状态。