设计模式之备忘录模式(行为型)

本文介绍了备忘录模式的概念,通过一个Originator和Caretaker的角色来保存和恢复对象状态。在游戏场景中,通过Role、RoleMemento和RoleCaretaker类实现了角色状态的存档和读档功能,展示了备忘录模式如何用于游戏进度的保存与恢复,确保在游戏状态改变后能够轻松恢复到先前状态。
摘要由CSDN通过智能技术生成

1、备忘录模式定义

备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样我们就可以将该对象复原到原先保存的状态。

很多时候我们需要记录一个对象的内部状态,允许用户取消不确定或者错误的操作,恢复到他原来的状态,备忘录模式就提供了这样一种可以恢复状态的机制,可以使我们比较方便的回到某一个历史状态,比如游戏的存档、数据库的事务等

2、备忘录模式结构

在这里插入图片描述

Originator(发起人):负责创建一个备忘录 Memento,用来记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。Originator 可以根据需要决定 Memento 存储 Originator 的哪些内部状态

import lombok.Data;

/**
 * 发起人
 */
@Data
public class Originator {

    // 需要保存的属性
    private String blood;
    private String status;

    public Originator() {
    }

    public Originator(String blood, String status) {
        this.blood = blood;
        this.status = status;
    }

    /**
     * 创建备忘录,将需要爆粗你的信息保存
     *
     * @return 备忘录对象
     */
    public Memento createMemento() {
        return new Memento(blood, status);
    }

    /**
     * 恢复备忘录,将 Memento 导入并将数据恢复
     */
    public void setMemento(Memento memento) {
        status = memento.getStatus();
        blood = memento.getBlood();
    }

    /**
     * 显示数据
     */
    public void show() {
        System.out.println("status = " + status + ",blood = " + blood);
    }
}

Memento(备忘录):负责存储 Originator 对象的内部状态

import lombok.Data;

/**
 * 备忘录
 */
@Data
public class Memento {

    private String blood;

    private String status;

    public Memento() {
    }

    public Memento(String blood, String status) {
        this.blood = blood;
        this.status = status;
    }

}

Caretaker(管理者):负责保存好备忘录 Memento,不能对备忘录内的内容进行操作或者检查

import lombok.Data;

/**
 * 管理者
 */
@Data
public class Caretaker {

    private Memento memento;

}

调用方代码

public class MementoClient {

    public static void main(String[] args) {
        // Originator 初始状态,血量 100,状态 on
        Originator originator = new Originator();
        originator.setStatus("on");
        originator.setBlood("100");
        originator.show();

        // 保存状态到管理者
        Caretaker caretaker = new Caretaker();
        Memento memento = originator.createMemento();
        caretaker.setMemento(memento);

        // 改变属性,状态 off,血量 10
        originator.setStatus("off");
        originator.setBlood("10");
        originator.show();

        // 恢复原来的状态
        originator.setMemento(caretaker.getMemento());
        originator.show();
    }

}
// status = on,blood = 100
// status = off,blood = 10
// status = on,blood = 100

备忘录模式将保存的细节封装到了 Memento 中,需要更改保存的细节的话不会影响到客户端

3、备忘录模式应用场景

  • Memento 模式适用于功能较为复杂,但需要维护或者记录属性历史的类,或者需要保存的属性只是其中的一部分,Originator 可以根据保存的 Memento 信息还原到前一状态
  • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,可以使用备忘录模式来存储可撤销操作的状态
  • 当角色的状态改变的时候,可能这个状态无效,使用备忘录可以将这个无效的状态复原

4、游戏进度备忘

一个游戏角色有生命力、攻击力、防御力等属性,可以中途退出并存档,重新进入后恢复角色状态

4.1 代码结构图

在这里插入图片描述

4.2 代码实现

Role:游戏角色类

import lombok.Data;

@Data
public class Role {

    /**
     * 攻击
     */
    private Integer attack;

    /**
     * 血量
     */
    private Integer blood;

    /**
     * 防御
     */
    private Integer defense;

    private void init() {
        this.defense = 100;
        this.blood = 100;
        this.attack = 5;
    }
    
    /**
     * 角色状态查看
     */
    public void show() {
        System.out.println("血量:" + blood + " 攻击:" + attack + " 防御:" + defense);
    }

    /**
     * 保存角色状态
     *
     * @return 角色状态备忘录
     */
    public RoleMemento save() {
        return RoleMemento.builder()
                .blood(blood)
                .attack(attack)
                .defense(defense)
                .build();
    }

    /**
     * 恢复角色状态
     */
    public void Recover(RoleMemento roleMemento) {
        this.defense = roleMemento.getDefense();
        this.blood = roleMemento.getBlood();
        this.attack = roleMemento.getAttack();
    }

}

RoleMemento:角色备忘录(角色状态存储)

import lombok.Builder;
import lombok.Data;

/**
 * 角色状态存储
 */
@Data
@Builder
public class RoleMemento {

    /**
     * 攻击
     */
    private Integer attack;

    /**
     * 血量
     */
    private Integer blood;

    /**
     * 防御
     */
    private Integer defense;

}

RoleCaretaker:角色状态管理

import lombok.Data;

/**
 * 角色管理者
 */
@Data
public class RoleCaretaker {

    private RoleMemento roleMemento;

}

调用代码:

public class GameClient {
    public static void main(String[] args) {
        Role zhangSan = new Role();
        // 角色初始化
        zhangSan.init();
        zhangSan.show();

        // 保存进度
        RoleCaretaker roleCaretaker = new RoleCaretaker();
        // 具体保存的数据没有透传出来
        roleCaretaker.setRoleMemento(zhangSan.save());

        // 角色战斗,数据下降
        zhangSan.fight();
        zhangSan.show();

        // 恢复状态
        zhangSan.recover(roleCaretaker.getRoleMemento());
        zhangSan.show();

    }
}
// 血量:100 攻击:5 防御:100
// 血量:20 攻击:5 防御:30
// 血量:100 攻击:5 防御:100
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起来搬砖呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值