※讓有紀錄保存需求的類別,自行產生要保存的資料,外界完全不用瞭解這些紀錄被產生的過程及來源。也讓類別自己從之前的保存資料找回資訊,自行重設類別狀態
下面是用備忘錄模式+Json做的存檔選單,先來看看備忘錄模式的UML的關係吧
備忘錄模式(Memento)
Originator(紀錄擁有者)
- 擁有紀錄的類別,內部有成員或記錄需要被儲存會自動將保存的紀錄產生出來,不比提供存取內部狀態的方法
- 會自動將資料從之前的保存紀錄中取回,並回復之前的狀態
public class Originator{
string m_State; //狀態,需要被保存
public void SetInfo(string State){
m_State = State;
}
public void ShowInfo(){
Debug.Log("Originator State:"+m_State);
}
public Memento CreateMemento(){
Memento newMmento = new Memento();
newMemento.SetState(m_State);
return newMemento;
}
//取回之前Memento紀錄的方法
public void SetMemento(Memento m){
m_State = m.GetState();
}
}
※定義:系統中擁有需要保存資訊的類別
Memento(記錄保存者)
- 負責保存Originator(紀錄擁有者)的內部資訊
- 無法取得Originator(紀錄擁有者)的資訊,必須由Originator(紀錄擁有者)主動設定及取用
public class Memento(){
string m_State;
public string State{
set{
m_State = value;
}
get{
return m_State ;
}
}
}
※定義:定義需要被儲存保留的成員,並針對這些成員設定存取方法
Caretaker(管理紀錄擁有者)
- 管理Originator(紀錄擁有者)產生出來的Memento(記錄保存者)
- 可以增加物件管理容器,來保存多個Memento(記錄保存者)
public class Caretaker{
Dictionary<string, Memento> m_Mementos = new Dictionary<string, Memento>();
//增加
public void AddMemento(string Version, Memento theMemento){
if(m_Mementos.ContainsKey(Version) == fales){
m_Mementos.Add(Version, theMemento);
}else{
m_Mementos[Version] = theMemento;
}
}
//取回
public Memento GetMemento(String Version){
if(m_Memento.ContaionKey(Version) == false){
return null;
}
return m_Memento[Version];
}
}
※定義:具備同時保留多個紀錄物件的功能,讓系統可以決定Originator(紀錄擁有者)要回復到哪一個版本
測試管理紀錄保存者
void UnitTest(){
Oringinator theOringinator = new Oringinator();
Caretaker theCaretaker = new Caretaker();
//設定資訊
theOringinator .SetInfo("Version1");
theOringinator .ShowInfo();
//保存
theCaretaker.AddMemento("1",theOringinator .CreateMemento());
//設定資訊
theOringinator .SetInfo("Version2");
theOringinator .ShowInfo();
//保存
theCaretaker.AddMemento("2",theOringinator .CreateMemento());
//設定資訊
theOringinator .SetInfo("Version3");
theOringinator .ShowInfo();
//保存
theCaretaker.AddMemento("3",theOringinator .CreateMemento());
//退回第二版
theOringinator.SetMemento(theCaretaker.GetMemento("2"));
theOringinator .ShowInfo();
//退回第一版
theOringinator.SetMemento(theCaretaker.GetMemento("1"));
theOringinator .ShowInfo();
}
執行結果:
Originator State:Version1
Originator State:Version2
Originator State:Version3
Originator State:Version2
Originator State:Version1
使用備忘錄的優點:
以遊戲成就系統為例,紀錄成就的功能就可以從成就系統中獨立出來,讓專責的成就存檔類別負責存檔工作,存檔功能的實作,成就系統也不必知道
成就系統也保有封裝性,不必對外開放過多的存取函式來取得內部狀態
以遊戲角色資訊存檔紀錄為例,可以存在多個紀錄,還可以選擇讀取那一份紀錄
然後存檔紀錄實作就等下一篇再寫
參考《設計模式與遊戲開發的完美結合》的DesignPattern-Memento 備忘錄模式