备忘录模式,这个模式理解、掌握起来不难,代码实现比较灵活,应用场景也比较明确和有限,主要是用来防丢失、撤销、恢复等。
1. 备忘录模式的原理
备忘录模式,也叫快照(Snapshot)模式,英文翻译是 Memento Design Pattern. 在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。
这个模式的定义主要表达了两部分内容。
- 一部分是,存储副本以便后期恢复。
- 另一部分是,要在不违背封装原则的前提下,也就是不能对外暴露细节,进行对象的备份和恢复。
备忘录模式与备忘的区别:
- 备忘录模式更侧重于代码的设计和实现。
- 备份更侧重架构设计或产品设计。
2. 备忘录模式的代码实现
type InputText struct {
text strings.Builder
}
func NewInputText() *InputText {
return &InputText{text: strings.Builder{}}
}
func (i *InputText) GetText() string {
return i.text.String()
}
func (i *InputText) Append(str string) {
i.text.WriteString(str)
}
func (i *InputText) CreateSnapshot() *Snapshot {
return NewSnapshot(i.GetText())
}
func (i *InputText) RestoreFromSnapshot(snapshot *Snapshot) {
i.text.Reset()
i.text.WriteString(snapshot.GetText())
}
type Snapshot struct {
text string
}
func NewSnapshot(text string) *Snapshot {
return &Snapshot{text: text}
}
func (s *Snapshot) GetText() string {
return s.text
}
// 客户端使用代码
func TestSnapshot(t *testing.T) {
input := NewInputText()
input.Append("hello, ")
input.Append("this is me. ")
t.Log(input.GetText())
snaphost := input.CreateSnapshot()
t.Log(snaphost.GetText())
input.Append("undo")
t.Log(input.GetText())
input.RestoreFromSnapshot(snaphost)
t.Log(input.GetText())
}
3. 备忘录模式的一些优化
主要是优化内存与时间消耗。假设每当有数据改动,都需要生成一个备份,以备之后恢复。如果需要备份的数据很大,这样高频率的备份,不管是对存储(内存或者硬盘)的消耗,还是对时间的消耗,都可能是无法接受的。想要解决这个问题,一般会采用“低频率全量备份”和“高频率增量备份”相结合的方法。
当需要恢复到某一时间点的备份的时候,如果这一时间点有做全量备份,直接拿来恢复就可以了。如果这一时间点没有对应的全量备份,就先找到最近的一次全量备份,然后用它来恢复,之后执行此次全量备份跟这一时间点之间的所有增量备份,也就是对应的操作或者数据变动。