wiki: 備忘錄模式是一種軟體設計模式:在不破壞封閉的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。這也是一種比較常見的設計模式,可以用來建立程式某個時刻執行狀態的快照,當程式異常崩潰或者因為其他原因導致退出後,可以使用備忘後的資料,恢復到原始狀態,最常見的操作應該就是編輯器的撤銷了,編輯器應用了備忘錄模式,將編輯過程中的**狀態放在乙個狀態棧中,當使用
ctrl+z
的時候,就從棧中彈出上一次儲存的狀態,來恢復到上一次的情況(即撤銷)。
(圖源網路)
看起來很簡單,當需要儲存狀態的時候,負責人從發起人處拿到狀態,然後儲存到備忘錄中,
當需要恢復的時候,負責人從備忘錄中拿出上乙個狀態,然後恢復到發起人中
備忘錄結構體
// 備忘錄
type memento struct
func
(m *memento)
setstate
(s string)
func
(m *memento)
getstate
()string
複製**
備忘錄結構體中的state
只是乙個單一的狀態,我們用乙個最簡單的字串形式來表示,在實際開發過程中,根據需要變為對應的資料結構,
如果是多狀態的,比如編輯器的撤銷操作,就儲存乙個棧。
發起人結構體
// 發起人
type originator struct
func
(o *originator)
setstate
(s string)
func
(o *originator)
getstate
()string
// 這裡就是規定了要儲存的狀態範圍
func
(o *originator)
creatememento
() *memento
}複製**
負責人結構體
// 負責人
type caretaker struct
func
(c *caretaker)
getmemento
() *memento
func
(c *caretaker)
setmemento
(m *memento)
複製**
搞一下...
func
main()
fmt.println("當前狀態:",o.getstate())
// 現在需要儲存當前狀態
// 就建立乙個負責人來設定(一般來說,對於乙個物件的同乙個備忘範圍,應當只有乙個負責人,這樣方便做多狀態多備忘管理)
c := new(caretaker)
c.setmemento(o.creatememento())
o.setstate("world")
fmt.println("更改當前狀態:",o.getstate())
// 恢復備忘
o.setstate(c.getmemento().getstate())
fmt.println("恢復後狀態",o.getstate())
}複製**
上面就是乙個單一狀態的備忘錄模式的完整流程了,還可以做很多操作,比如把儲存的備忘錄序列化成字串儲存在磁碟中,下次啟動的時候從磁碟中獲取狀態,這樣就可以做乙個簡單的快照了。
當然還有多狀態的,一般來說,乙個物件有乙個對應的備忘物件,記錄物件中要備忘的字段,而多個物件的備忘,同一由同乙個負責人進行管理,可以用map
來做到這一點,
負責人中的備忘容器是乙個map
型別的資料,值是乙個實現備忘介面的資料結構即可。
另外要注意一下備忘模式的優缺點:
缺點
上述**均放在 golang-design-patterns 這個倉庫中
打個廣告,推薦一下自己寫的 go web框架 bingo,求star,求pr ~
設計模式之備忘錄模式
機器 public class machine public void startplay disc.setluminance 60 disc.settime 0 disc.setvolume 80 public void stopplay disc.setluminance 70 disc.set...
設計模式之備忘錄模式
定義 在不破壞封閉的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。備忘錄模式有三個角色 以儲存遊戲進度為例,退出遊戲前存檔,再進入遊戲就會顯示退出之前的狀態。示例 遊戲發起人類 public class game public state cr...
設計模式之 備忘錄模式
定義 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣就可以將該物件 恢復到原先儲存的狀態。很好理解,就像我們以前打通關遊戲一樣,打通某個關卡,就會備份一下,不然根本通不了關。備忘錄 負責儲存發起人物件的內部狀態,在需要的時候提供發起人需要的內部狀態。public c...