大话设计模式——23.备忘录模式(Memento Pattern)

发布于:2024-04-15 ⋅ 阅读:(32) ⋅ 点赞:(0)

简介

又称快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并且该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

UML图

在这里插入图片描述

应用场景
  • 允许用户取消不确定或者错误的操作,能够恢复到原先的状态
  • 游戏存档、棋盘游戏悔棋,数据库事务回滚等
示例

游戏存档

  1. Originator:
public class GameOriginator {


    /**
     * 角色名称
     */
    private String name;
    /**
     * 血量
     */
    private int live;

    /**
     * 攻击力
     */
    private int attack;


    // 初始化状态
    public GameOriginator(String name) {
        this.name = name;
        this.live = 100;
        this.attack = 1;

    }

    /**
     * 进攻
     */
    public int fight() {
        if (this.live <= 0) {
            System.out.println("你输了!游戏结束。");
            return -1;
        }
        // 每次攻击少2滴血
        this.live -= 2;
        // 攻击力增加5
        this.attack += 5;
        return 0;
    }

    /**
     * 防御
     */
    public void defense() {
        // 血量增加1
        this.live += 1;
    }

    /**
     * 保存
     *
     * @return
     */
    public GameMemento saveState() {
        return new GameMemento(live, attack);
    }

    public void recoveryState(GameMemento gameMemento) {
        this.live = gameMemento.getLive();
        this.attack = gameMemento.getAttack();
    }


    public void display() {
        System.out.println("角色名称:" + name + ",血量:" + live + ",攻击力:" + attack);
    }
}
  1. Memento:保存角色的关键状态
public class GameMemento {

    private int live;

    private int attack;


    public GameMemento(int live, int attack) {
        this.live = live;
        this.attack = attack;
    }

    public int getLive() {
        return live;
    }


    public int getAttack() {
        return attack;
    }


}
  1. Caretaker:游戏管理界面
public class GameCaretaker {

    private GameMemento gameMemento;

    public GameMemento getGameMemento() {
        return gameMemento;
    }

    public void setGameMemento(GameMemento gameMemento) {
        this.gameMemento = gameMemento;
    }
}
  1. 运行
public class Main {

    public static void main(String[] args) {

        // 创建游戏角色
        GameOriginator gameRole = new GameOriginator("大大怪");
        gameRole.display();

        // 连击10次
        for (int i = 0; i < 10; i++) {
            gameRole.fight();
        }

        // 防御
        gameRole.defense();
        gameRole.display();

        // 保存状态
        System.out.println("存档。。。。");
        GameCaretaker gameCaretaker = new GameCaretaker();
        gameCaretaker.setGameMemento(gameRole.saveState());

        // 连击100次
        for (int i = 0; i < 100; i++) {
            if (gameRole.fight() == -1) {
                break;
            }
        }
        gameRole.display();

        // 恢复状态
        System.out.println("恢复存档。。。。");
        gameRole.recoveryState(gameCaretaker.getGameMemento());
        gameRole.display();

    }
}

在这里插入图片描述

总结

  • 优点
    • 提供了可以恢复的机制
    • 实现了信息的封装,用户不需要关心状态的保存细节
  • 缺点
    • 会占用较多的系统存储资源