天天看點

Java大話設計模式學習總結(十八)---備忘錄模式

備忘錄(Memento),在不破壞封裝性的前提下,捕獲一個對象的内部狀态,并在該對象之外儲存這個狀态。這樣以後就可以将該對象恢複到原先儲存的狀态。

Java大話設計模式學習總結(十八)---備忘錄模式

.舉例:

比如玩單機遊戲,一般打大boss前,或者需要下線了,都會把目前的狀态儲存一份,避免打boss死亡或者角色資料丢失,這個就可以用備忘錄模式來實作。

  1. 遊戲備忘錄類,記錄需要存檔的資料資訊
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 int getAtk() {
        return atk;
    }
    public int getDef() {
        return def;
    }
}
           
  1. 遊戲角色類
public class Player {

    // 生命力
    private int vit = 100;
    // 攻擊力
    private int atk = 100;
    // 防禦力
    private int def = 100;
    
    // 儲存角色狀态
    public RoleStateMemento saveState(){
        return new RoleStateMemento(vit, atk, def);
    }
    // 恢複角色
    public void RecoveryState(RoleStateMemento backup){
        this.vit = backup.getVit();
        this.atk = backup.getAtk();
        this.def = backup.getDef();
    }
    // 戰鬥
    public void fight(){
        Random random = new Random();
        this.vit = random.nextInt(99);
        this.atk = random.nextInt(99);
        this.def = random.nextInt(99);
    }
    // 展示屬性
    public void show(){
        System.out.println("生命力:" + vit + " 攻擊力:" + atk + " 防禦力:" + 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;
    }
}
           
  1. 遊戲角色狀态管理者
public class RoleAdmin {
    private RoleStateMemento roleStateMemento;
    public RoleStateMemento getRoleStateMemento() {
        return roleStateMemento;
    }
    public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
        this.roleStateMemento = roleStateMemento;
    }
}
           
  1. 主程式
public class Test {

    public static void main(String[] args) {
        Player player = new Player();
        player.show();
        // 儲存狀态
        RoleAdmin roleAdmin = new RoleAdmin();
        roleAdmin.setRoleStateMemento(player.saveState());
        // 開始戰鬥
        player.fight();
        player.show();
        // 狀态不好了,恢複到戰鬥前的狀态
        player.RecoveryState(roleAdmin.getRoleStateMemento());
        player.show();
    }

}
運作結果如下:
生命力:100 攻擊力:100 防禦力:100
生命力:24 攻擊力:22 防禦力:98
生命力:100 攻擊力:100 防禦力:100
           

總結:

備忘錄模式比較适用于功能比較複雜的,但需要維護或者記錄曆史屬性的類,或者需要儲存的屬性隻是衆多屬性中的一小部分時,Originator可以根據儲存的Memento資訊還原到前一狀态。如果狀态資料過大的話,備忘錄模式會非常消耗記憶體,在做java企業級應用時,一般都選擇定時将資料持久化到資料庫中做備份。