手撸golang 行为型设计模式 备忘录模式
手撸golang 行为型设计模式 备忘录模式
缘起
最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之
备忘录模式
备忘录模式(Memento Pattern)又叫作快照模式(Snapshot Pattern),或者令牌模式(Token Pattern),指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后即可将该对象恢复到原价保存的状态,属于行为型设计模式。备忘录模式主要适用于以下应用场景。(1)需要保存历史快照的场景。(2)希望在对象之外保存状态,且除了自己,其余类对象无法访问状态保存的具体内容。(摘自 谭勇德 <<设计模式就该这样学>>)场景
- 某线上博客平台, 需为客户提供在线编辑文章功能
- 文章主要包括标题 – title 和内容 – content等信息
- 为最大程度防止异常情况导致编辑内容的丢失, 需要提供版本暂存和Undo, Redo功能
- “版本暂存”问题可以应用备忘录模式, 将编辑器的状态完整保存(主要就是编辑内容)
- Undo和Redo的本质, 是在历史版本中前后移动
设计
- IEditor: 定义编辑器接口
- tEditorMemento: 定义编辑器的备忘录, 也就是编辑器的内部状态数据模型, 同时也对应一个历史版本
- tMockEditor: 虚拟的编辑器类, 实现IEditor接口
单元测试
memento_pattern_test.go
package behavioral_patternsimport ( "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_MementoPatterntMockEditor.Show, title=唐诗 登鹳雀楼 王之涣, content=白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。tMockEditor.Show, title=唐诗 登鹳雀楼, content=白日依山尽, 黄河入海流. tMockEditor.Show, title=唐诗, content=白日依山尽tMockEditor.Show, title=唐诗 登鹳雀楼, content=白日依山尽, 黄河入海流. tMockEditor.Show, title=唐诗 登鹳雀楼 王之涣, content=白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。--- PASS: Test_MementoPattern (0.00s)PASSok command-line-arguments 0.002sIEditor.go
定义编辑器接口
package mementotype IEditor interface { Title(title string) Content(content string) Save() Undo() error Redo() error Show()}tEditorMemento.go
定义编辑器的备忘录, 也就是编辑器的内部状态数据模型, 同时也对应一个历史版本
package mementoimport "time"type tEditorMemento struct { title string content string createTime int64}func newEditorMememto(title string, content string) *tEditorMemento { return &tEditorMemento{ title, content, time.Now().Unix(), }}tMockEditor.go
虚拟的编辑器类, 实现IEditor接口
package mementoimport ( "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)
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 手撸golang 行为型设计模式 备忘录模式
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 手撸golang 行为型设计模式 备忘录模式