行为型 - 8. 备忘录模式

135 阅读2分钟

备忘录模式,这个模式理解、掌握起来不难,代码实现比较灵活,应用场景也比较明确和有限,主要是用来防丢失、撤销、恢复等。

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. 备忘录模式的一些优化

主要是优化内存与时间消耗。假设每当有数据改动,都需要生成一个备份,以备之后恢复。如果需要备份的数据很大,这样高频率的备份,不管是对存储(内存或者硬盘)的消耗,还是对时间的消耗,都可能是无法接受的。想要解决这个问题,一般会采用“低频率全量备份”和“高频率增量备份”相结合的方法。

当需要恢复到某一时间点的备份的时候,如果这一时间点有做全量备份,直接拿来恢复就可以了。如果这一时间点没有对应的全量备份,就先找到最近的一次全量备份,然后用它来恢复,之后执行此次全量备份跟这一时间点之间的所有增量备份,也就是对应的操作或者数据变动。