bboyjing's blog

HeadFirst设计模式二十二【备忘录模式】

当有需要让对象返回之前的状态时,例如用户请求撤销操作,就可以使用备忘录模式。

场景描述

玩游戏时的存档就是一个很好的例子,比如游戏角色死掉后,恢复到存档时的状态。下面就来简单实现下。

代码示例

  1. 创建保存状态的Memento类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class GameMemento {
    private int hp;
    private int exp;
    public GameMemento(int hp, int exp) {
    this.hp = hp;
    this.exp = exp;
    }
    public int getHp() {
    return hp;
    }
    public int getExp() {
    return exp;
    }
    }
  2. 创建游戏角色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public class GamePlayer {
    // 角色生命值
    private int hp;
    // 角色经验值
    private int exp;
    public GamePlayer(int hp, int exp) {
    this.hp = hp;
    this.exp = exp;
    }
    /**
    * 生成状态快照
    */
    public GameMemento saveTMemento() {
    return new GameMemento(hp, exp);
    }
    /**
    * 恢复到快照状态
    *
    * @param memento
    */
    public void restoreFromMemento(GameMemento memento) {
    this.hp = memento.getHp();
    this.exp = memento.getExp();
    }
    /**
    * 模拟游戏过程
    */
    public void play(int hp, int exp) {
    this.hp += hp;
    this.exp += exp;
    }
    @Override
    public String toString() {
    return "GamePlayer{" +
    "hp=" + hp +
    ", exp=" + exp +
    '}';
    }
    }
  3. 创建保存快照的管理类,下面只演示保存一份快照,真实情况可以设计复杂的结构以保存多个时间点的快照。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class GameCaretaker {
    private GameMemento memento;
    public GameMemento getMemento() {
    return memento;
    }
    /**
    * 保存快照
    */
    public void setMemento(GameMemento memento) {
    this.memento = memento;
    }
    }
  4. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class Test {
    public static void main(String[] args) {
    GamePlayer player = new GamePlayer(100, 0);
    // 存档
    GameCaretaker caretaker = new GameCaretaker();
    caretaker.setMemento(player.saveTMemento());
    System.out.println(player);
    // 角色死亡
    player.play(-100, 10);
    System.out.println(player);
    // 回复到存档位置
    player.restoreFromMemento(caretaker.getMemento());
    System.out.println(player);
    }
    }

这个模式核心是把自身的状态以快照的方式保存到另外一个管理类中,以便发生意外时可以回档。本章节就到这里了。