大话设计模式之备忘录模式总结-java实现

注:示例来自《大话设计模式》

假如现有如下场景 游戏的某个场景 一游戏角色有生命力 攻击力 防御力等等数据 在打Boss前和后一定会不一样的 我们允许玩家如果感觉与Boss决斗的效果不理想 可以让游戏恢复到决斗前 简单代码实现如下

游戏角色类

package Test18;

public class GameRole {

    //生命力
    private int vit;
    //攻击力
    private int atk;
    //防御力
    private int def;

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }

    //状态显示
    public void StateDisplay()
    {
        System.out.println("角色当前状态:");
        System.out.println("体力:"+this.vit);
        System.out.println("攻击力:"+this.atk);
        System.out.println("防御力:"+this.def);
    }

    //获得初始状态
    public void GetInitState()
    {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    //战斗
    public void Fight()
    {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
}

客户端代码

package Test18;

public class Program {

    public static void main(String[] args) {

        //大战Boss前
        GameRole lixiaoyao = new GameRole();
        lixiaoyao.GetInitState();
        lixiaoyao.StateDisplay();

        //保存进度
        GameRole backup = new GameRole();
        backup.setVit(lixiaoyao.getVit());
        backup.setAtk(lixiaoyao.getAtk());
        backup.setDef(lixiaoyao.getDef());

        //大战Boss时,损耗严重
        lixiaoyao.Fight();
        lixiaoyao.StateDisplay();

        //恢复之前状态
        lixiaoyao.setVit(backup.getVit());
        lixiaoyao.setAtk(backup.getAtk());
        lixiaoyao.setDef(backup.getDef());

        lixiaoyao.StateDisplay();

    }

}

上面的写法把整个游戏角色的细节暴露给了客户端 我们应该把游戏角色的存取状态细节封装起来 下面我们使用备忘录模式进行重构 代码如下

游戏角色类

package Test18;

public class GameRole {

    //生命力
    private int vit;
    //攻击力
    private int atk;
    //防御力
    private int def;

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }

    //状态显示
    public void StateDisplay()
    {
        System.out.println("角色当前状态:");
        System.out.println("体力:"+this.vit);
        System.out.println("攻击力:"+this.atk);
        System.out.println("防御力:"+this.def);
    }

    //保存角色状态
    public RoleStateMemento SaveState()
    {
        return (new RoleStateMemento(vit, atk, def));
    }

    //恢复角色状态
    public void RecoveryState(RoleStateMemento memento)
    {
        this.vit = memento.getVit();
        this.atk = memento.getAtk();
        this.def = memento.getDef();
    }

    //获得初始状态
    public void GetInitState()
    {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    //战斗
    public void Fight()
    {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
}

角色状态存储箱类

package Test18;

//角色状态存储箱
public class RoleStateMemento {

    //生命力
    private int vit;
    //攻击力
    private int atk;
    //防御力
    private int def;

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }

    public RoleStateMemento(int vit, int atk, int def)
    {
        this.vit = vit;
        this.atk = atk;
        this.def = def;
    }

}

角色状态管理者类

package Test18;

//角色状态管理者
public class RoleStateCaretaker {

    private RoleStateMemento memento;

    public RoleStateMemento getMemento() {
        return memento;
    }

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


}

客户端代码

package Test18;

public class Program {

    public static void main(String[] args) {

        //大战Boss前
        GameRole lixiaoyao = new GameRole();
        lixiaoyao.GetInitState();
        lixiaoyao.StateDisplay();

        //保存进度
        RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
        stateAdmin.setMemento(lixiaoyao.SaveState());

        //大战Boss时,损耗严重
        lixiaoyao.Fight();
        lixiaoyao.StateDisplay();

        //恢复之前状态
        lixiaoyao.RecoveryState(stateAdmin.getMemento());

        lixiaoyao.StateDisplay();

    }

}

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

上面就是把要保存的细节给封装在了备忘录中了 哪一天要更改保存的细节也不用影响客户端了

备忘录模式比较适用于功能比较复杂的 但需要维护或记录属性历史的类 或者需要保存的属性只是众多属性中的一小部分时 发起人可以根据保存的备忘录信息还原到前一状态

如果在某个系统中使用命令模式时 需要实现命令的撤销功能 那么命令模式可以使用备忘录模式来存储可撤销操作的状态

使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来

当角色的状态改变的时候 有可能这个状态无效 这时候就可以使用暂时存储起来的备忘录将状态复原

缺点 如果状态数据很大很多 那么在资源消耗上 备忘录对象会非常耗内存

猜你喜欢

转载自blog.csdn.net/qq_26814945/article/details/82424953