備忘錄模式的用途很單純,就是提供物件回到之前狀態的功能,簡單說就是備份 (存檔) 的機制。備忘錄模式是一個在現實世界中很常使用到的模式,如遊戲的儲存記錄,文書編輯器的「上一步」功能等。簡單介紹完這個模式後,就來看一下正式的定義及類別圖吧:
參考資料:
深入淺出設計模式(Head First Design Patterns)
不違反封裝的情形下,取得物件的內部狀態。如此可以回復物件之前的狀態。
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
- Originator:就是定義中提到的要保留內部狀態的物件。現實例子就像是遊戲角色狀態,或是文書編輯器中的文字等。
- Memento:保留 Originator 內部狀態 (資料) 的物件,例如遊戲中要存檔的資料。
- Caretaker:主要功用是管理 Memento 物件。
看到這邊,我們應該能知道備忘錄模式有兩個目標:
- 儲存物件的重要狀態
- 維護物件的封裝
// Originator public class GamePlayer { // 遊戲角色的生命值 private int mHp; // 遊戲角色的經驗值 private int mExp; public GamePlayer(int hp, int exp) { mHp = hp; mExp = exp; } public GameMemento saveToMemento() { return new GameMemento(mHp, mExp); } public void restoreFromMemento(GameMemento memento) { mHp = memento.getGameHp(); mExp = memento.getGameExp(); } public void play(int hp, int exp) { mHp = mHp - hp; mExp = mExp + exp; } } // Memento public class GameMemento { // 假設只有這兩個資料要保留 private int mGameHp; private int mGameExp; public GameMemento(int hp, int exp) { mGameHp = hp; mGameExp = exp; } public int getGameHp() { return mGameHp; } public int getGameExp() { return mGameExp; } } // Caretaker public class GameCaretaker { // 保留要處理的資料。 // 這邊只是範例,所以 Caretaker // 只能處理一個 Memento。 // 實務上當然可以用更複雜的結構來 // 處理多個 Memento,如 ArrayList。 private GameMemento mMemento; public GameMemento getMemento() { return mMemento; } public void setMemento(GameMemento memento) { mMemento = memento; } } public class Demo { public static void main(String[] args) { // 創造一個遊戲角色 GamePlayer player = new GamePlayer(100, 0); // 先存個檔 GameCaretaker caretaker = new GameCaretaker(); caretaker.setMemento(player.seveToMemento()); // 不小心死掉啦 player.play(-100, 10); // 重新讀取存檔,又是一尾活龍 player.restoreFromMemento(caretaker.getMemento()); } }最後來總結一下吧。備忘錄模式的用途就是提供備份功能,因此這個模式的架構本身就設計的容易實作復原功能。也因為拆成了 Originator,Memento,Caretaker,除了讓物件的資料封裝不被破壞外,也提高了內聚力 (cohesion)。雖然範例的備份復原很簡單,但實務上 Memento 要保留的資料可能很多,會造成備份還原的時間很長,這是要注意的部份。另外,Java SDK 本身的 Serializable 以及 Android SDK 的 Parcelable 都算是很好的備忘錄模式實作,有興趣的人可以參考。
參考資料:
深入淺出設計模式(Head First Design Patterns)
留言
張貼留言