awesome-patterns/behavioral/memento/main.go

93 lines
1.6 KiB
Go
Raw Normal View History

2019-05-02 13:16:11 +03:00
// 备忘录模式 memento pattern
// 在不影响原结构封装的情况下,能够暂时保存一个结构的状态,并能够恢复
// 这里是一个游戏存档的例子,尝试保存玩家当前位置,并在读档的时候恢复
package main
import (
"container/list"
"log"
)
2019-05-03 05:48:46 +03:00
// originator
2019-05-02 13:16:11 +03:00
type Player struct {
2019-05-03 05:48:46 +03:00
// 需要记录的数据可以考虑单独封装
// type Pos struct{X,Y int}
2019-05-02 13:16:11 +03:00
X,Y int
2019-05-03 05:48:46 +03:00
2019-05-02 13:16:11 +03:00
// other info
2019-05-03 05:48:46 +03:00
Name string
2019-05-02 13:16:11 +03:00
}
func (p *Player)MoveTo(x,y int){
p.X = x
p.Y = y
}
func (p Player)Save()PlayerMemento{
return PlayerMemento{
X:p.X,
Y:p.Y,
}
}
func (p *Player)Restore(m PlayerMemento){
p.X = m.X
p.Y = m.Y
}
2019-05-03 05:48:46 +03:00
// memento
2019-05-02 13:16:11 +03:00
type PlayerMemento struct {
X,Y int
}
2019-05-03 05:48:46 +03:00
// caretaker
2019-05-02 13:16:11 +03:00
type PlayerCareTaker struct {
MementoList *list.List
}
func (ct *PlayerCareTaker)AddMemento(memento PlayerMemento){
ct.MementoList.PushFront(memento)
}
func (ct *PlayerCareTaker)RemoveLast()PlayerMemento{
ele := ct.MementoList.Front()
val := ct.MementoList.Remove(ele)
if memento ,ok := val.(PlayerMemento);ok{
return memento
}else{
return PlayerMemento{}
}
}
func main(){
ct := &PlayerCareTaker{list.New()}
icg := &Player{
X:114,
Y:514,
Name:"icg",
}
ct.AddMemento(icg.Save())
log.Println(icg.X ,icg.Y)
icg.MoveTo(810 ,19)
log.Println(icg.X ,icg.Y)
ct.AddMemento(icg.Save())
icg.MoveTo(0 ,0)
log.Println(icg.X ,icg.Y)
icg.Restore(ct.RemoveLast())
log.Println(icg.X ,icg.Y)
icg.Restore(ct.RemoveLast())
log.Println(icg.X ,icg.Y)
2019-05-03 05:48:46 +03:00
/*
output:
2019/05/02 18:18:03 114 514
2019/05/02 18:18:03 810 19
2019/05/02 18:18:03 0 0
2019/05/02 18:18:03 810 19
2019/05/02 18:18:03 114 514
*/
2019-05-02 13:16:11 +03:00
}