前言
這次要介紹的是備忘錄模式,也是行為模式的一種 。現在人們的智能手機上都會有備忘錄這樣一個功能,大家也都會用,就是為了記住某件事情,防止以后自己忘記了。那么備忘錄模式又是什么樣子的呢?是不是和手機上的備忘錄一樣呢?下面來介紹一下。
備忘錄模式
概念介紹
備忘錄模式是指在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以后就可以將該對象恢復到原先保存的狀態。簡單的來說就是平時玩的通關游戲,第一次前進了5步,第二次前進時踩到便便了,然后要回到之前的進度。例如下圖結構:
舉例
我們還是用一個小例子來簡單介紹一下備忘錄模式,在玩一個步驟游戲時,每走一步時步數都加一,遇到道具可以快速走幾步,或者減幾步。用備忘錄模式的思想來實現這個邏輯,就是如下代碼。
游戲類
/** * 游戲 */ @Data public class Game { /** * 玩家走的步數 */ private int playerStep; /** * 備份游戲 * @return */ public GameMemento createGameMemento(){ return new GameMemento(playerStep); } /** * 開始玩游戲 */ public void play(){ playerStep = 0; } /** * 恢復備份 * @param gameMemento */ public void restore(GameMemento gameMemento){ this.playerStep = gameMemento.getPlayerSteps(); } }
備份
/** * 備份 */ @Getter public class GameMemento { /** 步數 */ private int playerSteps; /** * 備份步數 * @param playerSteps */ public GameMemento(int playerSteps){ this.playerSteps = playerSteps; } }
備份信息管理類
/** * 備份信息管理類 */ public class Caretaker { /** 備份 */ private GameMemento gameMemento; /** 恢復備份 */ public GameMemento retrieveMemento(){ return this.gameMemento; } /** 保存備份 */ public void saveMemento(GameMemento gameMemento){ this.gameMemento = gameMemento; } }
測試
public class Player { public static void main(String[] args) { Game game = new Game(); System.out.println("游戲開始,撿到滑板,前進10步"); game.setPlayerStep(10); //備份當前狀態 System.out.println("備份當前狀態"); GameMemento gameMemento = game.createGameMemento(); Caretaker caretaker = new Caretaker(); caretaker.saveMemento(gameMemento); System.out.println("備份完成"); game.play(); System.out.println("踩到便便了,當前步數為:"+game.getPlayerStep()); System.out.println("還原到之前一步"); game.restore(caretaker.retrieveMemento()); System.out.println("恢復完成,當前玩家步數是:"+game.getPlayerStep()); } }
運行結果
游戲開始,撿到滑板,前進10步 備份當前狀態 備份完成 踩到便便了,當前步數為:0 還原到之前一步 恢復完成,當前玩家步數是:10
上面的這個例子使用了lombok插件的注解例如:@Getterhe@Data所以少寫了getter和setter方法。看完了這個小例子,大概應該知道備忘錄模式是個什么邏輯了吧,有點類似咱們平時知道的事務回滾的機制。下面還是分析一下,備忘錄模式都是由哪些部分組成的。
備忘錄模式結構
結構圖如下
備忘錄模式的構成角色如下所示。
原發器類(Originator):創建一個備忘錄對象,使用備忘錄存儲它的內部狀態。
負責人類(CareTaker):負責保存好備忘錄對象,不能檢查或操作備忘錄的內容。
備忘錄類(Memento):將原發器的內部狀態存儲起來,原發器根據需要決定備忘錄存儲原發器的哪些內部狀態。
總結
優點
1、它提供了一種狀態恢復的實現機制,使得用戶可以方便地回到一個特定的歷史步驟,當新的狀態無效或者存在問題時,可以使用暫時存儲起來的備忘錄將狀態復原。
2、備忘錄實現了對信息的封裝,一個備忘錄對象是一種原發器對象狀態的表示,不會被其他代碼所改動。備忘錄保存了原發器的狀態,采用列表、堆棧等集合來存儲備忘錄對象可以實現多次撤銷操作。
缺點
資源消耗過大,如果需要保存的原發器類的成員變量太多,就不可避免需要占用大量的存儲空間,每保存一次對象的狀態都需要消耗一定的系統資源。
適用場景
1、保存一個對象在某一個時刻的全部狀態或部分狀態,這樣以后需要時它能夠恢復到先前的狀態,實現撤銷操作。
2、防止外界對象破壞一個對象歷史狀態的封裝性,避免將對象歷史狀態的實現細節暴露給外界對象。
想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。