最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之golang
备忘录模式(Memento Pattern)又叫做快照模式(Snapshot Pattern), 或令牌模式(Token Pattern), 指在不破坏封装的前提下, 捕获一个对象的内部状态, 并在对象以外保存这个状态。 这样之后就可将该对象恢复到原先保存的状态, 属于行为型设计模式。 备忘录模式主要适用于如下应用场景。 (1)须要保存历史快照的场景。 (2)但愿在对象以外保存状态,且除了本身,其余类对象没法访问状态保存的具体内容。 (摘自 谭勇德 <<设计模式就该这样学>>)
memento_pattern_test.go设计模式
package behavioral_patterns import ( "learning/gooop/behavioral_patterns/memento" "testing" ) func Test_MementoPattern(t *testing.T) { editor := memento.NewMockEditor() // test save() editor.Title("唐诗") editor.Content("白日依山尽") editor.Save() editor.Title("唐诗 登鹳雀楼") editor.Content("白日依山尽, 黄河入海流. ") editor.Save() editor.Title("唐诗 登鹳雀楼 王之涣") editor.Content("白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。") editor.Save() // test show() editor.Show() // test undo() for { e := editor.Undo() if e != nil { break } else { editor.Show() } } // test redo() for { e := editor.Redo() if e != nil { break } else { editor.Show() } } }
$ go test -v memento_pattern_test.go === RUN Test_MementoPattern tMockEditor.Show, title=唐诗 登鹳雀楼 王之涣, content=白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。 tMockEditor.Show, title=唐诗 登鹳雀楼, content=白日依山尽, 黄河入海流. tMockEditor.Show, title=唐诗, content=白日依山尽 tMockEditor.Show, title=唐诗 登鹳雀楼, content=白日依山尽, 黄河入海流. tMockEditor.Show, title=唐诗 登鹳雀楼 王之涣, content=白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。 --- PASS: Test_MementoPattern (0.00s) PASS ok command-line-arguments 0.002s
定义编辑器接口app
package memento type IEditor interface { Title(title string) Content(content string) Save() Undo() error Redo() error Show() }
定义编辑器的备忘录, 也就是编辑器的内部状态数据模型, 同时也对应一个历史版本编辑器
package memento import "time" type tEditorMemento struct { title string content string createTime int64 } func newEditorMememto(title string, content string) *tEditorMemento { return &tEditorMemento{ title, content, time.Now().Unix(), } }
虚拟的编辑器类, 实现IEditor接口oop
package memento import ( "errors" "fmt" ) type tMockEditor struct { title string content string versions []*tEditorMemento index int } func NewMockEditor() IEditor { return &tMockEditor{ "", "", make([]*tEditorMemento, 0), 0, } } func (me *tMockEditor) Title(title string) { me.title = title } func (me *tMockEditor) Content(content string) { me.content = content } func (me *tMockEditor) Save() { it := newEditorMememto(me.title, me.content) me.versions = append(me.versions, it) me.index = len(me.versions) - 1 } func (me *tMockEditor) Undo() error { return me.load(me.index - 1) } func (me *tMockEditor) load(i int) error { size := len(me.versions) if size <= 0 { return errors.New("no history versions") } if i < 0 || i >= size { return errors.New("no more history versions") } it := me.versions[i] me.title = it.title me.content = it.content me.index = i return nil } func (me *tMockEditor) Redo() error { return me.load(me.index + 1) } func (me *tMockEditor) Show() { fmt.Printf("tMockEditor.Show, title=%s, content=%s\n", me.title, me.content) }
备忘录模式的优势 (1)简化发起人实体类(Originator)的职责,隔离状态存储与获取, 实现了信息的封装,客户端无须关心状态的保存细节。 (2)提供状态回滚功能。 备忘录模式的缺点 备忘录模式的缺点主要是消耗资源。 若是须要保存的状态过多,则每一次保存都会消耗不少内存。 (摘自 谭勇德 <<设计模式就该这样学>>)
(end)单元测试