博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式学习--备忘录模式

Posted on 2017-11-19 12:33  南国木棉  阅读(115)  评论(0编辑  收藏  举报

 

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

案例:模拟保存游戏进度;

代码结构图:

 1:创建游戏角色存储箱:

package MementoModel;

/**
* 角色状态存储箱,
* @author 我不是张英俊
*
*/
public class RoleStateMemento {

//生命力
private int vit;
//攻击力
private int atk;
//防御力
private int def;
public RoleStateMemento (int vit, int atk,int def){
//将生命力,攻击力,防御力存入状态存储箱对象中
this.vit=vit;
this.atk=atk;
this.def=def;

}
public RoleStateMemento() {
// TODO Auto-generated constructor stub
}

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;
}



}

2:创建游戏角色:

package MementoModel;

/**
 * 游戏玩家角色
 * @author 我不是张英俊
 *
 */
public class GamePlayer {
    
    private int vit;
    private int atk;
    private int def;
    

    //保存角色状态
    public RoleStateMemento saveState(){
        return (new RoleStateMemento(vit, atk, def));
    }
    
    //恢复游戏状态
    public void RecoveryState(RoleStateMemento memento){
        this.setVit(memento.getVit());
        this.setAtk(memento.getAtk());
        this.setDef(memento.getDef());
    }

    //状态显示
    public void stateDisplayer(){
        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;
    }
    
    //大战boss
    public void fight(){
        this.vit=0;
        this.def=0;
        this.atk=0;
    }
    
    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;
    }

}

:创建角色状态管理器;

package MementoModel;

/**
 * 角色状态管理者类
 * 当存储不同角色的状态时可以使用,因为不同角色可能状态不一致,有的觉得有特定的状态。
 * @author 我不是张英俊
 *
 */
public class RoleStateCaretaker {

    private RoleStateMemento memento;

    public RoleStateMemento getMemento() {
        return memento;
    }

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

4:创建测试类:

package MementoModel;

/**
 * 模拟存储游戏进度机制
 * 状态模式:(Memento)在不破坏封装性的前提下,补货一个对象的内部状态,
 * 并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。
 * @author 我不是张英俊
 *
 */
public class Test {

    public static void main(String[] args) {

        //大战boss前
        GamePlayer one=new GamePlayer();
        one.getInitState();
        one.stateDisplayer();
        
        //保存进度
        RoleStateCaretaker caretaker=new RoleStateCaretaker();
        caretaker.setMemento(one.saveState());
        
        //大战boss
        one.fight();
        one.stateDisplayer();
        //恢复状态
        one.RecoveryState(caretaker.getMemento());
        one.stateDisplayer();
    }

}

控制台:

状态显示:
生命值:100
攻击力:100
防御力:100
状态显示:
生命值:0
攻击力:0
防御力:0
状态显示:
生命值:100
攻击力:100
防御力:100

总结:Memento模式比较适用于功能比较复杂的,但需要维护活记录实行历史信息的类,或者需要保存的树形只是

众多树形中的一小部分。例如:如果某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。

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

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

学习疑问:是否可以通过克隆来存储当前状态?