设计模式GOF23——备忘录模式

备忘录模式(memento),是一种行为性模型,行为型模式关注的是系统中对象之间的相互交互,解决系统在运行时对象之间的相互通信和协作,进一步明确对象的职责。相比来说,创建型模式关注对象的创建过程,结构型模式关注对象和类的组合关系。

模式的职责

我们对一些操作,需要有保存状态,甚至需要恢复到之前状态的要求,这个时候可以使用备忘录模式。备忘录模式实际是要保存之前的状态,用来让机器可以恢复到之前的状态。

模式的结构

源发器类:被记录备忘的类
备忘录类:存储备忘信息的类
负责人类:保存和管理备忘录类的类(因为可能需要保存不止一个备忘信息)。

模式的实现

//需要存储的对象
public class PlayLoad {
    //存储对象的属性
    private String PlayLevel;
    private int hp;
    private int mp;
    //存储对象的构造方法
    public PlayLoad(String level,int hp,int mp){
        this.PlayLevel = level;
        this.hp = hp;
        this.mp = mp;
    }
    //进行备忘信息,并返回备忘的备份
    public Memento memento(){
        return new Memento(this);
    }
    //取出备忘信息的方法
    public void recovery(Memento memento){
        this.PlayLevel = memento.getPlayLevel();
        this.hp = memento.getHp();
        this.mp = memento.getMp();
    }
    //相应属性的set和get方法
    public String getPlayLevel() {
        return PlayLevel;
    }
    public void setPlayLevel(String playLevel) {
        PlayLevel = playLevel;
    }
    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 class Memento {
    private String PlayLevel;
    private int hp;
    private int mp;
    public Memento(PlayLoad load){
        this.PlayLevel = load.getPlayLevel();
        this.hp = load.getHp();
        this.mp = load.getMp();
    }

    public String getPlayLevel() {
        return PlayLevel;
    }
    public void setPlayLevel(String playLevel) {
        PlayLevel = playLevel;
    }
    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 class CareTaker {
    //由于备忘信息的特殊性,所以一般用栈来存储(其实这里更的情况更适合用List或者map存储,但是需要更多的判断)
    private Stack<Memento>stack = new Stack<Memento>();
    //取得最新存储信息
    public Memento popM() {
        return stack.pop();
    }
    //放入存储信息
    public void pushtM(Memento m) {
        this.stack.push(m);
    }

}
//客户端调用
public class Client {

    public static void main(String[] args) {
        //新建负责人类对象
        CareTaker c = new CareTaker();
        //新建被备忘对象
        PlayLoad p = new PlayLoad("第一关",2000,1900);
        System.out.println("现在是"+p.getPlayLevel()+",还有血量"+p.getHp()+",还有魔法值"+p.getMp());
        //第一次备忘
        Memento m =p.memento();
        //将备忘信息放入负责人对象中
        c.pushtM(m);
        p.setHp(1800);
        p.setMp(1700);
        p.setPlayLevel("第二关");
        System.out.println("现在是"+p.getPlayLevel()+",还有血量"+p.getHp()+",还有魔法值"+p.getMp());
        m = p.memento();
        c.pushtM(m);
        p.setHp(100);
        p.setMp(100);
        p.setPlayLevel("第三关");
        System.out.println("现在是"+p.getPlayLevel()+",还有血量"+p.getHp()+",还有魔法值"+p.getMp());
        p.recovery(c.popM());
        System.out.println("现在是"+p.getPlayLevel()+",还有血量"+p.getHp()+",还有魔法值"+p.getMp());
        p.recovery(c.popM());
        System.out.println("现在是"+p.getPlayLevel()+",还有血量"+p.getHp()+",还有魔法值"+p.getMp());
    }

}

输出的结果为:
现在是第一关,还有血量2000,还有魔法值1900
现在是第二关,还有血量1800,还有魔法值1700
现在是第三关,还有血量100,还有魔法值100
现在是第二关,还有血量1800,还有魔法值1700
现在是第一关,还有血量2000,还有魔法值1900

由此可见备忘信息已经可以成功的存储和取出。

模式的其他说明

其实本例子更应该用Map的方式去存储,因为游戏的存档读档对于顺序没有太高的要求,反而需要客户端能明白自己要调用的存储信息是哪个,用Map的键值对存储更适合。
但是对于像文档操作,软件操作的存档,比较适合用State去存储,因为一般恢复都是就近的操作存档进行恢复。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值