close

※讓有紀錄保存需求的類別,自行產生要保存的資料,外界完全不用瞭解這些紀錄被產生的過程及來源。也讓類別自己從之前的保存資料找回資訊,自行重設類別狀態

下面是用備忘錄模式+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 備忘錄模式

arrow
arrow

    Kouhei 發表在 痞客邦 留言(0) 人氣()