文章目录
- 1. 概述
- 1.1 角色
- 1.2 类图
- 2. 代码示例
- 2.1 设计
- 2.2 代码
- 2.3 类图
1. 概述
备忘录(Memento)用于在不破坏目标对象封装特性的基础上,将目标对象内部的状态存储到外部对象中,以备之后恢复状态时使用。
1.1 角色
- Originator(发起者):当前的基础对象,它会将自己的状态保存进备忘录。
- savememento()方法:Originator通过该方法将它自己状态保存进一个备忘录对象。
- restorememento()方法:Originator通过该方法将它自己状态回滚至指定备忘录。
- Memento(备忘录) : 存储Originator状态的对象
- Caretaker(管理者):保存多条备忘录的对象,并维护着备忘录的索引,在需要的时候会返回相应的备忘录。
1.2 类图
2. 代码示例
2.1 设计
- 定义备忘录
memento
来记录发起者状态 - 它的
Get()
方法获取它的状态 - 定义发起者
Originator
- 它的方法
CreateMemento()
用它自己创建一条备忘录 - 它的方法
RollBack()
将它自己回滚至指定备忘录的状态 - 它的
Set()
方法可以设置它的状态 - 它的
Get()
方法可以获取它的状态
- 它的方法
- 创建一个管理者
Caretaker
,它是备忘录Memento
的聚合- 它的
AddMemento
方法,向它自身加入一条备忘录 - 它的
GetMemento()
方法,查询一条它管理的指定备忘录
- 它的
- 调用
- 初始化
- 实例化一个管理者
caretaker
- 实例化一个发起者
originator
- 实例化一个管理者
- 创建备忘录测试
- 第一次
- 用发起者创建一条备忘录
- 管理者收录该备忘录
- 第二次
- 改变发起者状态
- 用发起者创建一条新备忘录
- 管理者收录该备忘录
- 第三次
- 改变发起者状态
- 用发起者创建一条新备忘录
- 管理者收录该备忘录
- 查看管理者信息,应该有三条备忘录
- 第一次
- 回滚测试
- 从管理者获取指定索引的备忘录
- 将发起者回滚至该备忘录状态
- 初始化
2.2 代码
- 代码
package mainimport "fmt"// 定义备忘录
type Memento struct {state string
}// 查备忘录状态
func (m *Memento) Get() string {return m.state
}// 定义发起者
type Originator struct {state string
}// 根据发起者状态创建一条备忘录
func (e *Originator) CreateMemento() (memento *Memento) {memento = &Memento{state: e.state}fmt.Printf("创建一条备忘录:%+v\n", memento)return memento
}// 将发起者状态回滚至指定备忘录状态
func (e *Originator) RollBack(m *Memento) {e.state = m.Get()fmt.Printf("发起者状态回滚至:%v\n", e)
}// 设置发起者状态
func (e *Originator) Set(state string) {e.state = statefmt.Println("发起者状态更改为:", e.state)
}// 获取发起者状态
func (e *Originator) Get() string {fmt.Println("获取发起者状态为:", e.state)return e.state
}// 定义管理者,管理者是备忘录的聚合
type Caretaker struct {mementoArray []*Memento
}// 向管理者中添加一条备忘录
func (c *Caretaker) AddMemento(m *Memento) {fmt.Printf("向管理者中添加一条备忘录:%+v\n", m)c.mementoArray = append(c.mementoArray, m)
}// 获取指定备忘录信息
func (c *Caretaker) GetMemento(index int) *Memento {fmt.Printf("获取到第 %d 条备忘录信息为:%+v\n", index, c.mementoArray[index])return c.mementoArray[index]
}func main() {//实例化一个管理者caretaker := &Caretaker{mementoArray: make([]*Memento, 0),}//实例化一个发起者originator := &Originator{state: "A",}//为发起者创建一条备忘录memento0 := originator.CreateMemento()//在管理者中加入该备忘录caretaker.AddMemento(memento0)//改变发起者状态originator.Set("B")//为发起者创建第二条备忘录memento1 := originator.CreateMemento()//在管理者中加入该备忘录caretaker.AddMemento(memento1)//再次改变发起者状态originator.Set("C")//为发起者创建第三条备忘录memento2 := originator.CreateMemento()//在管理者中加入该备忘录caretaker.AddMemento(memento2)fmt.Println("此时管理者应该有三条备忘录:")for _, memento := range caretaker.mementoArray {fmt.Printf("%+v\n", memento)}fmt.Println("=========回滚测试===========")originator.RollBack(caretaker.GetMemento(1))fmt.Println("=========回滚测试===========")originator.RollBack(caretaker.GetMemento(0))
}
- 输出
创建一条备忘录:&{state:A}
向管理者中添加一条备忘录:&{state:A}
发起者状态更改为: B
创建一条备忘录:&{state:B}
向管理者中添加一条备忘录:&{state:B}
发起者状态更改为: C
创建一条备忘录:&{state:C}
向管理者中添加一条备忘录:&{state:C}
此时管理者应该有三条备忘录
&{state:A}
&{state:B}
&{state:C}
=========回滚测试===========
获取到第 1 条备忘录信息为:&{state:B}
发起者状态回滚至:&{B}
=========回滚测试===========
获取到第 0 条备忘录信息为:&{state:A}
发起者状态回滚至:&{A}