备忘录模式
备忘录模式是一种行为设计模式,它允许保存和恢复对象的内部状态,而无需暴露该对象的实现细节。这种模式在实现撤销操作或是需要保存和恢复数据的场景中非常有用。
核心组件
备忘录模式主要包含三个角色:
- 发起人(Originator):负责创建一个含有其当前内部状态的备忘录,并可以使用备忘录来恢复其内部状态。
- 备忘录(Memento):负责存储发起人的内部状态,并防止发起人以外的对象访问备忘录。备忘录有两个接口,管理者只能看到一个窄接口,它只允许将备忘录传给其他对象。发起人则能看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
- 管理者(Caretaker):负责保存备忘录,但不修改备忘录,也不直接操作备忘录的内容。管理者通过保存备忘录可以记录发起人对象的状态,用于未来的恢复。
工作原理
- 发起人创建一个备忘录对象,将其当前内部状态作为备忘录的内容保存起来。
- 管理者请求发起人创建一个新的备忘录,并将其保存在备忘录列表中。管理者可以按需存储或删除备忘录。
- 当需要恢复到某个历史状态时,管理者从备忘录列表中取出对应的备忘录,并将其交给发起人。发起人使用备忘录中的状态进行自身状态的恢复。
设计意图
备忘录模式的设计意图是允许在不违反封装的情况下,捕获并外部化对象的内部状态,以便以后可以将该对象恢复到定义的状态。备忘录模式提供了一种机制,记录对象的当前状态,并在需要时将对象恢复到这个状态。
优点
- 封装性好:备忘录模式提供了一种封装状态的机制,使得客户不需要关心状态的保存细节。
- 简化发起人:发起人不需要管理和保存其内部状态的历史记录,所有状态管理的责任都由管理者承担,这简化了发起人的职责。
缺点
- 资源消耗:如果发起人的状态需要大量资源来存储,频繁地创建备忘录可能会消耗大量资源。
- 难以维护:随着发起人状态的增多,管理者的工作量和存储需求也会增大。
代码实践
下面是一个使用 Go 语言实现的备忘录模式的例子。我们将创建一个简单的计算器程序,该程序能够保存历史计算结果,并能够回退到之前的状态。
首先,我们定义备忘录结构体 Memento
,用于保存状态:
package main
import "fmt"
// Memento struct
type Memento struct {
state int
}
func (m *Memento) GetSavedState() int {
return m.state
}
接着,我们定义发起人结构体 Originator
,它将使用 Memento
来保存和恢复状态:
// Originator struct
type Originator struct {
state int
}
func (o *Originator) SetState(state int) {
o.state = state
}
func (o *Originator) SaveStateToMemento() *Memento {
return &Memento{state: o.state}
}
func (o *Originator) GetStateFromMemento(memento *Memento) {
o.state = memento.GetSavedState()
}
func (o *Originator) GetState() int {
return o.state
}
然后,定义管理者 Caretaker
,它负责保存和获取备忘录对象:
// Caretaker struct
type Caretaker struct {
mementoList []*Memento
}
func (c *Caretaker) Add(memento *Memento) {
c.mementoList = append(c.mementoList, memento)
}
func (c *Caretaker) Get(index int) *Memento {
return c.mementoList[index]
}
最后,我们可以在 main
函数中使用这些结构体来模拟保存和恢复状态的操作:
func main() {
originator := &Originator{}
caretaker := &Caretaker{}
originator.SetState(100)
caretaker.Add(originator.SaveStateToMemento())
originator.SetState(200)
caretaker.Add(originator.SaveStateToMemento())
originator.SetState(300)
fmt.Printf("Current State: %d\n", originator.GetState())
// Restoring to the first saved state
originator.GetStateFromMemento(caretaker.Get(0))
fmt.Printf("First saved State: %d\n", originator.GetState())
// Restoring to the second saved state
originator.GetStateFromMemento(caretaker.Get(1))
fmt.Printf("Second saved State: %d\n", originator.GetState())
}
在这个例子中,Originator
类用于表示一个简单的状态(这里是一个整数)。我们可以设置这个状态,保存到备忘录,或者从备忘录中恢复。Caretaker
管理这些备忘录,允许我们保存多个状态并在需要时恢复它们。在 main
函数中,我们演示了如何保存状态并在之后恢复到这些状态。
总结
总之,备忘录模式提供了一种有效的方式来处理对象状态的保存和恢复,但需要权衡其对资源的消耗和实际应用场景的需求。
标签:originator,状态,模式,备忘录,state,发起人,设计模式,Memento From: https://www.cnblogs.com/zhifwu/p/18440766