备忘录模式——让你有后悔药吃

目录

一、基础简介

1、定义

2、使用场景

3、优缺点

4、模式结构分析

二、模式实例

1、Originator (发起人)

2、Memento (备忘录)

3、Caretaker(管理者)

4、客户端

5、结果


一、基础简介

1、定义

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。便于以后将该对象恢复到原先保存的状态

2、使用场景

 1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

 应用实例: 1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctri + z。 4、IE 中的后退。 4、数据库的事务管理。

3、优缺点

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

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

4、模式结构分析

  1. Originator (发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator 可根据需要决定Memento存储Originator的哪些内部状态。
  2. Memento (备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker 只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator 能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据
  3. Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

二、模式实例

场景:玩游戏时,我们都习惯去保存游戏进度,以防备角色over后,从某一个进度接着打boss

1、Originator (发起人)

package com.mfc.design.备忘录模式;

/**
 * @author MouFangCai
 * @date 2019/10/18 17:18
 *
 * 发起人:需要 保存的对象
 */
public class GameRole_Originator {

    private String name;
    /**
     * 生命值
     */
    private int life;

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

    /**
     * 当前游戏 关数 如:1-1
     */
    private String level;


    // 保存进度
    public Role_Memento saveGame(){
        return new Role_Memento(life, atk, level);
    }

    // 恢复角色状态
    public void recoveryGame(Role_Memento role_memento){
        this.life = role_memento.getLife();
        this.atk = role_memento.getAtk();
        this.level = role_memento.getLevel();
    }

    public void gameInit(String name){
       setName(name);
       setAtk(100);
       setLife(500);
       setLevel("1-1");
    }

    public void fight(){
        setLife(getLife() - 100);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    @Override
    public String toString() {
        return "当前角色信息{" +
                "name='" + name + '\'' +
                ", life=" + life +
                ", atk=" + atk +
                "-----当前关卡:'" + level + '\'' +
                '}';
    }
}

2、Memento (备忘录)

package com.mfc.design.备忘录模式;

/**
 * @author MouFangCai
 * @date 2019/10/18 17:27
 *
 * 备忘录:游戏储存箱,定义需要备忘的属性
 */
public class Role_Memento {

    /**
     * 我们在此保存3个属性
     */
    private int life;

    private int atk;

    private String level;

    // 将想要保存的属性 存入 储存箱中
    public Role_Memento(int life, int atk, String level) {
        this.life = life;
        this.atk = atk;
        this.level = level;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }
}

3、Caretaker(管理者)

package com.mfc.design.备忘录模式;

/**
 * @author MouFangCai
 * @date 2019/10/18 17:34
 *
 * 游戏备忘录管理者
 */
public class Game_Caretaker {

    private Role_Memento roleMemento;

    public Role_Memento getRoleMemento() {
        return roleMemento;
    }

    public void setRoleMemento(Role_Memento roleMemento) {
        this.roleMemento = roleMemento;
    }
}

4、客户端

package com.mfc.design.备忘录模式;

/**
 * @author MouFangCai
 * @date 2019/10/18 17:37
 */
public class Client_Memento {

    public static void main(String[] args) {

        GameRole_Originator gameRole = new GameRole_Originator();
        gameRole.gameInit("拳王");
        System.out.println("初始状态:" + gameRole.toString());

        // 打怪
        gameRole.fight();

        // 保存游戏进度
        Game_Caretaker gameCaretaker = new Game_Caretaker();
        gameCaretaker.setRoleMemento(gameRole.saveGame());
        System.out.println("保存进度:" + gameRole.toString());

        // 打怪
        gameRole.fight();
        gameRole.fight();
        System.out.println("打怪后,感觉打不过了:" + gameRole.toString());

        // 恢复游戏进度
        gameRole.recoveryGame(gameCaretaker.getRoleMemento());
        System.out.println("恢复的进度为:" + gameRole.toString());
    }
}

5、结果

初始状态:当前角色信息{name='拳王', life=500, atk=100-----当前关卡:'1-1'}
保存进度:当前角色信息{name='拳王', life=400, atk=100-----当前关卡:'1-1'}
打怪后,感觉打不过了:当前角色信息{name='拳王', life=200, atk=100-----当前关卡:'1-1'}
恢复的进度为:当前角色信息{name='拳王', life=400, atk=100-----当前关卡:'1-1'}

Process finished with exit code 0

发布了101 篇原创文章 · 获赞 176 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_36095679/article/details/102628683