深入理解23种设计模式(18) -- 备忘录模式

703 阅读2分钟

介绍

  1. 备忘录模式(Memento Pattern)在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将这个对象恢复到原先的状态
  2. 备忘录模式是一种对象行为型模式
  3. 可以使用备忘录来记录一些比较重要的或者容易遗忘的信息、游戏存档、数据库的事务回滚

在这里插入图片描述

  • Originator : 是发起人,负责记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

  • Memento : 是备忘录,负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

  • Caretaker : 是管理者,对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

案例

游戏存档 :

  • 获取用户生命值,体力,攻击力打怪,打怪途中消耗体力,生命值增强攻击力

创建游戏用户 GameRole 类

@Data
public class GameRole {

    /**
     * 生命值
     */
    private Integer vit;

    /**
     * 体力
     */
    private Integer phy;

    /**
     * 攻击力
     */
    private Integer atk;

    //获取状态
    public void getState() {
        System.out.println("游戏角色当前状态:");
        System.out.println("生命值: " + this.vit);
        System.out.println("体力:" + this.phy);
        System.out.println("攻击力:" + this.atk);
        System.out.println("-----------------");
    }

    /**
     * 初始化生命值
     */
    public GameRole() {
        this.vit = 100;
        this.atk = 100;
        this.phy = 100;
    }

    /**
     * 战斗后
     * @param vit
     * @param atk
     * @param phy
     */
    public void fightAfter(Integer vit,Integer atk,Integer phy) {
        this.phy = this.phy == null || this.phy == 0 ? 100 - phy : this.vit - phy;
        this.vit = this.vit == null || this.vit == 0 ? 100 - vit : this.vit - vit;
        this.atk = this.atk == null || this.atk == 0 ? 100 - atk : this.atk - atk;
    }


    /**
     * 保存角色状态
     * @return
     */
    public RoleStateMemento saveState() {
        return (new RoleStateMemento(vit, atk, phy));
    }

    /**
     * 恢复角色状态
     * @param memento
     */
    public void recoveryState(RoleStateMemento memento) {
        this.vit = memento.getVit();
        this.atk = memento.getAtk();
        this.phy = memento.getPhy();
    }


}

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             创建用户备忘录  RoleStateMemento 类
@Data
public class RoleStateMemento {

    /**
     * 生命值
     */
    private Integer vit;

    /**
     * 体力
     */
    private Integer phy;

    /**
     * 攻击力
     */
    private Integer atk;

    public RoleStateMemento(Integer vit, Integer phy, Integer atk) {
        this.vit = vit;
        this.phy = phy;
        this.atk = atk;
    }
}

创建管理者 RoleStateCaretaker 类

public class RoleStateCaretaker {

    private RoleStateMemento memento;

    public RoleStateMemento getMemento() {
        return memento;
    }

    public void setMemento(RoleStateMemento memento) {
        this.memento = memento;
    }
}

客户端

public class Client {

    public static void main(String[] args) {
        //创建游戏角色
        GameRole gameRole = new GameRole();
        gameRole.getState();
        RoleStateCaretaker caretaker = new RoleStateCaretaker();
        caretaker.setMemento(gameRole.saveState());
        gameRole.fightAfter(1,1,1);
        gameRole.getState();
        //恢复状态
        gameRole.recoveryState(caretaker.getMemento());
        gameRole.getState();
        gameRole.fightAfter(5,5,5);
        gameRole.getState();
        //恢复状态
        gameRole.recoveryState(caretaker.getMemento());
        gameRole.getState();
    }
}

在这里插入图片描述

优点和缺点

优点:

1)给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便的回到某个历史的状态。
2)实现了信息的封装,使得用户不需要关心状态的保存细节。

缺点:

 1)消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存

适用场景:

 1) 记录一些比较重要的或者容易遗忘的信息
 2)游戏存档
 3)Windows 里的  ctrl + z
 4) 数据库事务管理 


github Demo地址 : ~~~传送门~~~

个人博客地址:blog.yanxiaolong.cn/