走穿java23种设计模式--20备忘录模式详解

版权声明:本文为博主原创文章。只要评论中留言就可以转载。 https://blog.csdn.net/wenzhi20102321/article/details/80468151

走穿java23种设计模式–20备忘录模式详解

备忘录模式,又称快照模式或者Token模式。

一.备忘录模式的现实场景

卢康喜欢玩仙剑奇侠传单机游戏,每闯过一关他都会存档备份一下,防止在下一关的时候打不过去。如果下一关他打不过去,游戏角色死掉了,游戏结束,他可以通过备份重新进去之前备份的地方,直到通过下一关,最终完美通关。
在上面场景中,卢康游戏存档和读档的这两个过程类似于设计模式中的备忘录模式。

二.备忘录模式(Memento Pattern)的定义

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

三.备忘录模式的类图

1

四.备忘录模式的三个角色

1.发起人(Originator)角色

该角色记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘数据。

2.备忘录(Memento)角色

该角色负责存储发起人角色的内部状态,在必要时提供发起人需要的内部状态数据。

3.负责人(Caretaker)角色

该角色对备忘录角色进行管理、保存以及提供备忘录。

五.备忘录模式的使用场景

1.需要保存和恢复数据的相关状态场景。

2.需要提供一个可滚动的操作。

3.需要监控副本的场景中。

4.数据库连接的事务管理使用的就是备忘录模式。

五.备忘录模式的注意事项

1.备忘录的生命周期

备忘录创建出来就要在附近代码使用,系统主动管理它的生命周期,建立就要使用,不使用就要立刻删除其引用,等待垃圾回收机制对它进行回收。

2.备忘录的性能

不要在频繁建立备份的场景中使用备忘录模式。
例如,for循环中不宜使用备忘录模式,原因有两点:
(1)不能控制备忘录建立的对象数量;
(2)大对象的建立要消耗大量的资源,系统的性能需要重新考虑。

七.备忘录模式的示例

这里使用上面的现实场景做代码示例。

示例的类图

这里写图片描述

示例的代码

1.发起人角色GamePlayer


package p20_memento;

/**
 * 发起人角色,
 * 用来储存需要备份的游戏角色信息和行为
 */
public class GamePlayer {
    private String name;//
    private int hp;//血量
    private int mp;//精气量
    private int level;//等级

    public GamePlayer(String name, int hp, int mp, int level) {
        this.name = name;
        this.hp = hp;
        this.mp = mp;
        this.level = level;

    }

    //各属性的get、set
    public String getName() {
        return name;
    }

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

    public int getHp() {
        return hp;
    }

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

    public int getMp() {
        return mp;
    }

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

    public int getLevel() {
        return level;
    }

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

    //保存备份角色信息
    public GameBackup saveBackup() {
        System.out.println("保存游戏角色备份。。。");
        return new GameBackup(name, hp, mp, level);
    }

    //恢复游戏角色
    public void resumePlayer(GameBackup backup) {
        name = backup.getName();
        hp = backup.getHp();
        mp = backup.getMp();
        level = backup.getLevel();
    }

    //闯关
    public void killBoss() {
        System.out.println(name + "开始打Boss");
        double hpBoss = 100;
        while (hp > 0) {
            System.out.println(name + "使用技能攻击Boss");
            hpBoss = hpBoss - Math.random() * 80;
            if (hpBoss <= 0) {
                break;
            }
            mp = mp - 30;
            System.out.println("剩余血量:" + hp + "\t剩余精气量" + mp);

            System.out.println( "Boss攻击" + name);
            hp = hp - 50;
        }

        if (hp <= 0) {
            System.out.println("游戏角色:" + name + "被Boss杀死,Boss还有+" + (int) hpBoss + "+血。");
        } else if (hpBoss <= 0) {
            System.out.println("游戏角色:" + name + "杀死Boss开始下一关。");
        }

    }

    @Override
    public String toString() {
        return "游戏角色名:" + name + "\n" +
                "血量:" + hp + "\n" +
                "精气量" + "\n" +
                "等级" + level + "\n";
    }
}

2.备忘录角色GameBackup

package p20_memento;

/**
 * 备忘录角色,
 * 存储备份游戏角色的各个属性
 */
public class GameBackup {
    private String name;
    private int hp;
    private int mp;
    private int level;

    public GameBackup(String name,int hp,int mp,int level){
        this.name=name;
        this.hp=hp;
        this.mp=mp;
        this.level=level;
    }

    public String getName() {
        return name;
    }

    public int getHp() {
        return hp;
    }

    public int getMp() {
        return mp;
    }

    public int getLevel() {
        return level;
    }
}

3.负责人角色CaretakePlayer

package p20_memento;

/**
 * 负责人角色,
 * 控制备份
 */
public class CaretakePlayer {

    //游戏备份对象
    private GameBackup backup;

    public GameBackup getBackup() {
        return backup;
    }

    public void setBackup(GameBackup backup) {
        this.backup = backup;
    }

}

4.测试类

package p20_memento;

/**
 * 测试类
 */
public class MementoDemo {

    public static void main(String[] args) {
        //创建人物
        GamePlayer player = new GamePlayer("习伟", 100, 100, 1);
        //控制备份数据的对象
        CaretakePlayer caretakePlayer = new CaretakePlayer();
        //进行备份
        caretakePlayer.setBackup(player.saveBackup());

        //打怪
        player.killBoss();

        //恢复备份
        player.resumePlayer(caretakePlayer.getBackup());
        System.out.println("====================================");
        System.out.println("满血复活。。。");
        System.out.println("====================================");
        //继续打怪
        player.killBoss();

    }
}

程序运行结果;

这里写图片描述

共勉; 我仍然继续努力,心存谦卑心怀希望,不是努力所得的,总觉得不是属于我的。

猜你喜欢

转载自blog.csdn.net/wenzhi20102321/article/details/80468151
今日推荐