最近複習設計模式
拜讀譚勇德的<<設計模式就該這樣學>>
本系列筆記擬採用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)單元測試