From da2587d3f2fc0331e8f55ba0f888367f3a8e08f3 Mon Sep 17 00:00:00 2001 From: nynicg Date: Thu, 2 May 2019 18:16:11 +0800 Subject: [PATCH] memento pattern --- README.md | 2 +- behavioral/mediator/main.go | 4 +- behavioral/memento/main.go | 78 +++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 behavioral/memento/main.go diff --git a/README.md b/README.md index 56a6c98..e96ca76 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ A curated collection of idiomatic design & application patterns for Go language. | [Chain of Responsibility](/behavioral/chain_of_responsibility/main.go) | Avoids coupling a sender to receiver by giving more than object a chance to handle the request | ✔ | | [Command](/behavioral/command/main.go) | Bundles a command and arguments to call later | ✔ | | [Mediator](/behavioral/mediator/main.go) | Connects objects and acts as a proxy | ✔ | -| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✘ | +| [Memento](/behavioral/memento/main.go) | Generate an opaque token that can be used to go back to a previous state | ✔ | | [Observer](/behavioral/observer.md) | Provide a callback for notification of events/changes to data | ✔ | | [Registry](/behavioral/registry.md) | Keep track of all subclasses of a given class | ✘ | | [State](/behavioral/state.md) | Encapsulates varying behavior for the same object based on its internal state | ✘ | diff --git a/behavioral/mediator/main.go b/behavioral/mediator/main.go index 90d0d5c..ac20b50 100644 --- a/behavioral/mediator/main.go +++ b/behavioral/mediator/main.go @@ -1,8 +1,8 @@ // 中介者模式(mediator pattern) -// 当两个对象存在复杂的依赖关系时,考虑增加一个中介者使之解耦,使他们不需要进行显示的引用. +// 当两个对象存在复杂的依赖关系时,考虑增加一个中介者使之解耦,使他们不需要进行显式的引用. // 但问题在于中介本身会去实现复杂的逻辑,进而导致中介者变得复杂臃肿难以维护. // -// 这里是竞价和消息交换的例子. +// 这里是竞价的例子. // 参与竞价的玩家只需要向中介出价就可以知道是否能买到商品,由中介确定谁的出价高 package main diff --git a/behavioral/memento/main.go b/behavioral/memento/main.go new file mode 100644 index 0000000..5e6428a --- /dev/null +++ b/behavioral/memento/main.go @@ -0,0 +1,78 @@ +// 备忘录模式 memento pattern +// 在不影响原结构封装的情况下,能够暂时保存一个结构的状态,并能够恢复 +// 这里是一个游戏存档的例子,尝试保存玩家当前位置,并在读档的时候恢复 +package main + +import ( + "container/list" + "log" +) + +type Player struct { + X,Y int + Name string + // other info +} + +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 +} + +type PlayerMemento struct { + X,Y int +} + +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) +}