我們以遊戲為例子,遊戲者有等級、金錢欄位,透過備忘錄模式來儲存遊戲者的等級、金錢。
建立Originator:GamePlayer,欄位有等級level、錢money, createMemento為儲存功能、setMemento為還原功能
// Originator
class GamePlayer {
//角色的等級
var level: Int = 0
//身上的錢
var money: Int = 0
//產生備忘錄(存檔)
fun createMemento():Memento{
return Memento(level, money)
}
//還原備忘錄(回復)
fun setMemento(memento: Memento){
level = memento.level
money = memento.money
}
}
Memento:用來儲存Originator的結構(遊戲存檔的結構)
Caretaker:存檔、取檔都要透過Caretaker。
//Memento 遊戲存檔的結構。
data class Memento (val level: Int, val money: Int)//存放存檔的物件,這個每個存檔都會覆蓋之前的記錄,如果要存多個檔,可使用List
class Caretaker{
var memento: Memento? = null
}
Client
遊戲開始的角色設定
val player = GamePlayer()
player.level = 2
player.money = 300
println("一開始角色的等級:${player.level}, 金錢:${player.money}")
存檔,透過Caretaker存檔。
//存檔
val caretaker = Caretaker()
caretaker.memento = player.createMemento()
角色死掉了,將角色等級、金錢歸零
//死掉了,等級、金錢歸0
player.level = 0
player.money = 0
println("角色死掉了,等級:${player.level}, 金錢:${player.money}")
要執行復原,一樣要透過Caretaker取出存檔
//執行復原,取出存檔
player.setMemento(caretaker.memento!!)
println("角色復原了,等級:${player.level}, 金錢:${player.money}")
執行結果
一開始角色的等級:2, 金錢:300
角色死掉了,等級:0, 金錢:0
角色復原了,等級:2, 金錢:300
總結一下,Caretaker主要用來管理Memento 物件,也就是儲檔、取檔都透過Caretaker。而Memento則是用來保留 Originator 內部狀態,也就是要儲存的遊戲者的等級及金錢。Originator則是遊戲的角色狀態。
備忘錄模式除了儲存狀態也能儲存演算法,例如在玩象棋時的回上一步功能,我們可能就會在每一步儲存單一棋子移動的方式,而不是將當下所有的棋子狀態儲存下來。
在使用備忘錄模式時,也要考慮到時效性問題、及如果儲存的資料太多會有記憶體問題。