设计模式:备忘录模式示例

文章目录

示例一

让我们设计一个更复杂的场景:一个角色状态管理系统,用于游戏中角色的状态保存和恢复。在游戏中,角色可能会经历战斗,其生命值(HP)、魔法值(MP)和金币(Gold)等属性会发生变化。玩家可以在任何时刻保存当前的状态,并在需要时恢复到之前保存的状态。

定义备忘录类(Memento)

java 复制代码
public class CharacterMemento {
    private int hp;
    private int mp;
    private int gold;

    public CharacterMemento(int hp, int mp, int gold) {
        this.hp = hp;
        this.mp = mp;
        this.gold = gold;
    }

    public int getHp() {
        return hp;
    }

    public int getMp() {
        return mp;
    }

    public int getGold() {
        return gold;
    }
}

定义发起人类(Originator)

java 复制代码
public class GameCharacter {
    private int hp;
    private int mp;
    private int gold;

    public GameCharacter(int hp, int mp, int gold) {
        this.hp = hp;
        this.mp = mp;
        this.gold = gold;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public void setMp(int mp) {
        this.mp = mp;
    }

    public void setGold(int gold) {
        this.gold = gold;
    }

    public int getHp() {
        return hp;
    }

    public int getMp() {
        return mp;
    }

    public int getGold() {
        return gold;
    }

    public CharacterMemento saveState() {
        return new CharacterMemento(hp, mp, gold);
    }

    public void restoreState(CharacterMemento memento) {
        this.hp = memento.getHp();
        this.mp = memento.getMp();
        this.gold = memento.getGold();
    }
}

定义看护人类(Caretaker)

java 复制代码
import java.util.Stack;

public class Caretaker {
    private Stack<CharacterMemento> history = new Stack<>();

    public void saveState(GameCharacter character) {
        history.push(character.saveState());
    }

    public void restoreState(GameCharacter character) {
        if (!history.isEmpty()) {
            character.restoreState(history.pop());
        }
    }
}

使用备忘录模式

java 复制代码
public class Main {
    public static void main(String[] args) {
        GameCharacter character = new GameCharacter(100, 50, 10);
        Caretaker caretaker = new Caretaker();

        // 保存初始状态
        caretaker.saveState(character);

        // 状态变化
        character.setHp(80);
        character.setMp(30);
        character.setGold(20);
        System.out.println("After battle: HP=" + character.getHp() + ", MP=" + character.getMp() + ", Gold=" + character.getGold());

        // 恢复到初始状态
        caretaker.restoreState(character);
        System.out.println("After restore: HP=" + character.getHp() + ", MP=" + character.getMp() + ", Gold=" + character.getGold());
    }
}

输出:

复制代码
After battle: HP=80, MP=30, Gold=20
After restore: HP=100, MP=50, Gold=10

在这个例子中,GameCharacter类是发起人,它能够保存自己的状态到备忘录对象CharacterMemento中,也能从备忘录对象恢复状态。Caretaker类负责维护这些备忘录对象的历史记录,但不对这些对象进行操作或检查。这个示例展示了备忘录模式在游戏角色状态管理中的应用,帮助实现了角色状态的保存和恢复功能。

示例二

定义备忘录类(Memento)

java 复制代码
public class GameMemento {
    private final int lifePoints;
    private final String location;
    private final int gold;

    public GameMemento(int lifePoints, String location, int gold) {
        this.lifePoints = lifePoints;
        this.location = location;
        this.gold = gold;
    }

    public int getLifePoints() {
        return lifePoints;
    }

    public String getLocation() {
        return location;
    }

    public int getGold() {
        return gold;
    }
}

定义发起人类(Originator)

java 复制代码
public class GameCharacter {
    private int lifePoints;
    private String location;
    private int gold;

    public void setLifePoints(int lifePoints) {
        this.lifePoints = lifePoints;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public void setGold(int gold) {
        this.gold = gold;
    }

    // 保存状态到备忘录
    public GameMemento save() {
        return new GameMemento(lifePoints, location, gold);
    }

    // 从备忘录恢复状态
    public void restore(GameMemento memento) {
        this.lifePoints = memento.getLifePoints();
        this.location = memento.getLocation();
        this.gold = memento.getGold();
    }
}

定义看护人类(Caretaker)

java 复制代码
import java.util.Stack;

public class GameSaver {
    private Stack<GameMemento> mementos = new Stack<>();

    public void saveGame(GameCharacter character) {
        mementos.push(character.save());
    }

    public void loadGame(GameCharacter character) {
        if (!mementos.isEmpty()) {
            character.restore(mementos.pop());
        }
    }
}

使用备忘录模式

java 复制代码
public class Main {
    public static void main(String[] args) {
        GameCharacter character = new GameCharacter();
        GameSaver saver = new GameSaver();

        // 初始状态
        character.setLifePoints(100);
        character.setLocation("Village");
        character.setGold(50);
        System.out.println("Initial state");

        // 游戏进行,状态改变
        character.setLifePoints(80);
        character.setLocation("Dungeon");
        character.setGold(100);
        System.out.println("Game progressed, state changed");

        // 保存游戏
        saver.saveGame(character);

        // 继续游戏,状态再次改变
        character.setLifePoints(30);
        character.setLocation("Deep Dungeon");
        character.setGold(150);
        System.out.println("Game progressed further, state changed again");

        // 加载游戏,恢复到之前的状态
        saver.loadGame(character);
        System.out.println("Game loaded, state restored");
    }
}

在这个例子中,GameCharacter类代表游戏中的角色,它可以保存自己的状态到GameMemento备忘录中,并能从备忘录中恢复状态。GameSaver类充当看护人的角色,负责管理备忘录,实现游戏的存档和读档功能。

这个简化的游戏存档例子展示了备忘录模式在实际应用中的应用方式,通过这种方式,我们可以在不暴露GameCharacter内部状态的前提下,实现游戏状态的保存和恢复。

相关推荐
70后写java的老码农6 分钟前
Spring Boot 3.x + ShardingSphere 5.x + MyBatis-Plus 3.x:订单分库分表实战(含两个踩坑记录)
java
霸道流氓气质10 分钟前
AI 翻译插件:翻译记忆级联复用、术语混合检索与结构化质量门禁的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
斯维赤16 分钟前
OCR到底是接入第三方API 还是自己封装?
java·ocr
码智社33 分钟前
Redis 哨兵模式详解:从原理到生产实践
java·redis
救救孩子把42 分钟前
结构化输出为何“格式正确、答案错误”?JSON Schema 的能力边界
android·java·json·agent·agent服务
silvamux_1 小时前
微头条爆款体平台适配实测:把交付要求变成可计算的指标
java·线性代数·算法·决策树·矩阵
论文复现现场1 小时前
DeepSeek V4.1 Flash 和 V4 Pro 有什么区别?API 价格、性能与迁移建议
java·服务器·人工智能·python·大模型api·deepseek·deepseek v4.1
郭小李1 小时前
转发与重定向
java·服务器·数据库
你看我名字1 小时前
数眼智能 Search + Reader 实战:联网问答怎样避免“搜到了,却引用错了”
android·java·开发语言
MetaLite2 小时前
Spring Boot 加了 @Valid,嵌套参数为什么还没校验?
java·spring boot·后端