備忘錄模式(Memento Pattern)保存一個對象的某個狀態,以便在適當的時候恢復對象。備忘錄模式屬於行爲型模式。java
所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態,這樣能夠在之後將這個對象恢復到原先保存的狀態。git
備忘錄模式主要包含如下幾個角色:github
Originator(發起人):負責建立一個備忘錄Memento,用以記錄當前時刻它的內部狀態,並可以使用備忘錄恢復狀態。Originator可根據需求決定Memento存儲Originator的哪些內部狀態。this
Memento(備忘錄):負責存儲Originator對象的內部狀態,並可防止Originator之外的其餘對象訪問備忘錄Memento。備忘錄有兩個接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其餘對象。Originator可以看到一個寬接口,容許它訪問返回到先前狀態所需的全部數據。code
Caretaker(管理者):負責保存好備忘錄Memento,不能對備忘錄的內容進行操做或檢查。對象
備忘錄基本代碼接口
發起人(Originator)類遊戲
public class Originator { //須要保存的屬性 private String state; //建立備忘錄,將當前須要保存的信息導入並實例化出一個Memento對象 public Memento createMemento() { return new Memento(state); } //恢復備忘錄,將Memento導入並將相關數據恢復 public void setMemento(Memento memento) { this.state = memento.getState(); } //顯示數據 public void show() { System.out.println("state = " + state); } public String getState() { return state; } public void setState(String state) { this.state = state; } }
備忘錄(Memento)類內存
public class Memento { private String state; //構造方法,將相關數據導入 public Memento(String state) { this.state = state; } public String getState() { return state; } public void setState(String state) { this.state = state; } }
管理者(Caretaker)類資源
public class Caretaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
客戶端程序
public class Client { public static void main(String[] args) { Originator originator = new Originator(); originator.setState("On"); originator.show(); Caretaker caretaker = new Caretaker(); caretaker.setMemento(originator.createMemento()); originator.setState("Off"); originator.show(); originator.setMemento(caretaker.getMemento()); originator.show(); } }
運行結果
state = On state = Off state = On
實現場景:遊戲中的某個場景,一遊戲角色有生命力、攻擊力、防護力等數據,在打Boss前和後必定會不同的,咱們容許玩家若是感受與Boss決鬥的效果不理想可讓遊戲恢復到決鬥以前。
代碼結構圖
遊戲角色類
public class GameRole { private int vit; //生命力 private int atk; //攻擊力 private int def; //防護力 //初始化狀態 public void initState() { this.vit = 100; this.atk = 100; this.def = 100; } //戰鬥 public void fight() { this.vit = 0; this.atk = 0; this.def = 0; } //保存角色狀態 public RoleStateMemento saveState() { return new RoleStateMemento(vit, atk, def); } //回覆角色狀態 public void recoverState(RoleStateMemento roleStateMemento) { this.vit = roleStateMemento.getVit(); this.atk = roleStateMemento.getAtk(); this.def = roleStateMemento.getDef(); } public void stateDisplay() { System.out.println("角色生命力:" + vit); System.out.println("角色攻擊力:" + atk); System.out.println("角色防護力:" + def); } public int getVit() { return vit; } public void setVit(int vit) { this.vit = vit; } public int getAtk() { return atk; } public void setAtk(int atk) { this.atk = atk; } public int getDef() { return def; } public void setDef(int def) { this.def = def; } }
遊戲狀態存儲類
public class RoleStateMemento { private int vit; private int atk; private int def; public RoleStateMemento(int vit, int atk, int def) { this.vit = vit; this.atk = atk; this.def = def; } public int getVit() { return vit; } public void setVit(int vit) { this.vit = vit; } public int getAtk() { return atk; } public void setAtk(int atk) { this.atk = atk; } public int getDef() { return def; } public void setDef(int def) { this.def = def; } }
角色狀態管理者類
public class RoleStateCaretaker { private RoleStateMemento roleStateMemento; public RoleStateMemento getRoleStateMemento() { return roleStateMemento; } public void setRoleStateMemento(RoleStateMemento roleStateMemento) { this.roleStateMemento = roleStateMemento; } }
客戶端程序
public class Client { public static void main(String[] args) { System.out.println("------------大戰Boss前------------"); //大戰Boss前 GameRole gameRole = new GameRole(); gameRole.initState(); gameRole.stateDisplay(); //保存進度 RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker(); roleStateCaretaker.setRoleStateMemento(gameRole.saveState()); System.out.println("------------大戰Boss後------------"); //大戰Boss時,損耗嚴重 gameRole.fight(); gameRole.stateDisplay(); System.out.println("------------恢復以前狀態------------"); //恢復以前狀態 gameRole.recoverState(roleStateCaretaker.getRoleStateMemento()); gameRole.stateDisplay(); } }
運行結果
------------大戰Boss前------------ 角色生命力:100 角色攻擊力:100 角色防護力:100 ------------大戰Boss後------------ 角色生命力:0 角色攻擊力:0 角色防護力:0 ------------恢復以前狀態------------ 角色生命力:100 角色攻擊力:100 角色防護力:100
優勢
實現了信息的封裝,使得用戶不須要關心狀態的保存細節。
給用戶提供了一種能夠恢復狀態的機制,可使用戶可以比較方便地回到某個歷史的狀態。
缺點
不少時候咱們老是須要記錄一個對象的內部狀態,這樣作的目的是爲了容許用戶取消不肯定或者錯誤的操做,可以恢復到他原先的狀態,使得他有"後悔藥"可吃。
文章做者:leisurexi
新博客地址:https://leisurexi.github.io/
許可協議: 署名-非商業性使用-禁止演繹 4.0 國際 轉載請保留原文連接及做者。