java学习快到碗里来Java 核心技术Java 进阶

设计模式(十八)备忘录模式

2021-01-22  本文已影响0人  我犟不过你

1、概述

备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

2、适用场景

1)当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。
2)对象自行创建自己的快照,不希望其他对象对其进行访问,保证安全性。

3、实例

有以下实例:

有一款游戏,支持随时存档和读档。
在打boss前,小明进行了存档:
当前角色攻击力为1000,防御力为800,生命值为10000。
打boss没有打过,角色属性全部清空。
使用备忘录。

创建角色:

package com.cloud.bssp.designpatterns.memento;

/**
 * 游戏角色
 * @date: 2021/1/18
 * @author weirx
 * @version 3.0
 */
public class GameRole {

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

    /**
     * 防御力
     */
    private Long defense;

    /**
     * 生命值
     */
    private Long hp;


    public GameRole(Long atk, Long defense, Long hp) {
        this.atk = atk;
        this.defense = defense;
        this.hp = hp;
    }

    public GameRole() {
    }

    public void state() {
        System.out.println("--------当前角色信息--------");
        System.out.println("攻击力:" + this.atk);
        System.out.println("防御力:" + this.defense);
        System.out.println("血量:" + this.defense);
    }

    public void getInstance() {
        this.atk = 1000L;
        this.defense = 800L;
        this.hp = 10000L;
    }

    public void fight() {
        this.atk = 0L;
        this.defense = 0L;
        this.hp = 0L;
    }

    public Memento save() {
        return new Memento(this.atk, this.defense, this.hp);
    }

    public void read(Memento memento) {
        this.atk = memento.getAtk();
        this.defense = memento.getDefense();
        this.hp = memento.getHp();
    }

    public Long getAtk() {
        return atk;
    }

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

    public Long getDefense() {
        return defense;
    }

    public void setDefense(Long defense) {
        this.defense = defense;
    }

    public Long getHp() {
        return hp;
    }

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

创建备忘录:

package com.cloud.bssp.designpatterns.memento;

/**
 * 存档备忘录
 * @date: 2021/1/18
 * @author weirx
 * @version 3.0
 */
public class Memento {

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

    /**
     * 防御力
     */
    private Long defense;

    /**
     * 生命值
     */
    private Long hp;

    public Memento(Long atk, Long defense, Long hp) {
        this.atk = atk;
        this.defense = defense;
        this.hp = hp;
    }

    public Long getAtk() {
        return atk;
    }

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

    public Long getDefense() {
        return defense;
    }

    public void setDefense(Long defense) {
        this.defense = defense;
    }

    public Long getHp() {
        return hp;
    }

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

创建管理者:

package com.cloud.bssp.designpatterns.memento;

/**
 * 管理者
 * @date: 2021/1/22
 * @author weirx
 * @version 3.0
 */
public class Caretaker {

    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

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

创建测试客户端:

package com.cloud.bssp.designpatterns.memento;

/**
 * TODO
 * @date: 2021/1/22
 * @author weirx
 * @version 3.0
 */
public class TestDemo {

    public static void main(String[] args) {

        //创建角色并初始化
        GameRole gameRole = new GameRole();
        gameRole.getInstance();
        //获取当前角色状态
        gameRole.state();
        //存档
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(gameRole.save());
        //战斗
        gameRole.fight();
        //获取角色状态
        gameRole.state();
        //读档
        gameRole.read(caretaker.getMemento());
        //获取角色状态
        gameRole.state();
    }
}

结果:

--------当前角色信息--------
攻击力:1000
防御力:800
血量:800
--------当前角色信息--------
攻击力:0
防御力:0
血量:0
--------当前角色信息--------
攻击力:1000
防御力:800
血量:800

4、分析

上面几个类的关系如下图所示:

GameRole.png

1)TestDemo创建了Caretaker和GameRole,并且依赖于这两个类。
2)Caretaker则由Memento组成,依赖于Memento。
3)GameRole创建了Memento,依赖于Memento。

客户端不能直接去操作备忘录,需要通过管理者Caretaker。

5、总结

优点:
1)你可以在不破坏对象封装情况的前提下创建对象状态快照。
2)实现了信息的封装,使得用户不需要关心状态的保存细节。
3)给用户提供了一种可以恢复状态的机制,可以使用能够比较方便地回到某个历史的状态。
缺点:
消耗资源。

上一篇 下一篇

猜你喜欢

热点阅读