浅谈Java设计模式——备忘录模式(Memento)

一、概述

        在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。它实现了对信息的封装,使得客户不需要关心状态保存的细节。保存就要消耗资源,所以备忘录模式的缺点就在于消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

二、使用场景

1.必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。 

2.如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

三、参与者

1.Memento 备忘录存储原发器对象的内部状态。

2.Originator 原发器创建一个备忘录,用以记录当前时刻它的内部状态。 使用备忘录恢复内部状态.。

3.Caretaker 负责保存好备忘录。 不能对备忘录的内容进行操作或检查。

四、类图

五、示例代码

1.Memento

/**
 * Memento
 * @author zhipeng_Tong
 */
public class RoleStateMemento {
    private int liftValue;
    private int attachPower;
    private int defensivePower;

    public RoleStateMemento(int liftValue, int attachPower, int defensivePower) {
        this.liftValue = liftValue;
        this.attachPower = attachPower;
        this.defensivePower = defensivePower;
    }

    public int getLiftValue() {
        return liftValue;
    }

    public void setLiftValue(int liftValue) {
        this.liftValue = liftValue;
    }

    public int getAttachPower() {
        return attachPower;
    }

    public void setAttachPower(int attachPower) {
        this.attachPower = attachPower;
    }

    public int getDefensivePower() {
        return defensivePower;
    }

    public void setDefensivePower(int defensivePower) {
        this.defensivePower = defensivePower;
    }
}

2.Originator

/**
 * Originator
 * @author zhipeng_Tong
 */
public class GameRole {
    private int liftValue;  // 生命值
    private int attachPower;    // 攻击力
    private int defensivePower; // 防御力

    public int getLiftValue() {
        return liftValue;
    }

    public void setLiftValue(int liftValue) {
        this.liftValue = liftValue;
    }

    public int getAttachPower() {
        return attachPower;
    }

    public void setAttachPower(int attachPower) {
        this.attachPower = attachPower;
    }

    public int getDefensivePower() {
        return defensivePower;
    }

    public void setDefensivePower(int defensivePower) {
        this.defensivePower = defensivePower;
    }

    // 展示状态
    public void displayState() {
        System.out.println("角色状态信息: ");
        System.out.println(String.format("生命值: %d", liftValue));
        System.out.println(String.format("攻击力: %d", attachPower));
        System.out.println(String.format("防御力: %d", attachPower));
    }

    // 初始化状态
    public void initialState() {
        this.liftValue = 100;
        this.attachPower = 100;
        this.defensivePower = 100;
    }

    // 战斗
    public void fight() {
        this.liftValue = 0;
        this.attachPower = 0;
        this.defensivePower = 0;
    }

    // 保存角色状态
    public RoleStateMemento saveState() {
        return new RoleStateMemento(this.liftValue, this.attachPower, this.defensivePower);
    }

    // 回复角色状态
    public void recoveryState(RoleStateMemento memento) {
        this.liftValue = memento.getLiftValue();
        this.attachPower = memento.getAttachPower();
        this.defensivePower = memento.getDefensivePower();
    }
}

3.Caretaker

/**
 * Caretaker
 * @author zhipeng_Tong
 */
public class RoleStateCaretaker {
    private RoleStateMemento memento;

    public RoleStateMemento getMemento() {
        return memento;
    }

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

4.测试代码

public class Client {
    public static void main(String[] args) {
        // 大战boss前
        // 初始化游戏角色初始状态,三项指标都为100
        GameRole gameRole = new GameRole();
        gameRole.initialState();
        gameRole.displayState();

        // 保存进度信息
        RoleStateCaretaker caretaker = new RoleStateCaretaker();
        caretaker.setMemento(gameRole.saveState());

        // 大战boss,损耗严重
        gameRole.fight();
        gameRole.displayState();

        // 回复到之前状态
        gameRole.recoveryState(caretaker.getMemento());
        gameRole.displayState();
    }
}

运行结果:

角色状态信息: 
生命值: 100
攻击力: 100
防御力: 100
角色状态信息: 
生命值: 0
攻击力: 0
防御力: 0
角色状态信息: 
生命值: 100
攻击力: 100
防御力: 100

 

posted @ 2018-11-19 17:49  小情绪Ango  阅读(194)  评论(0编辑  收藏  举报