设计模式-备忘录模式

79 阅读2分钟

备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内 部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保 存的状态;可以这里理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情, 或者是记录已经达成的共同意见的事情,以防忘记了。而在软件层面,备忘录 模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某 些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作;备忘录模式属于行为型模式。

1.类图

image.png

2.代码

//源对象
public class GameRole {

    private int vit;//攻击力
    private int def;//防御力

    //创建Memento,根据当前状态得到Memento
    public Memento createMemento(){
        Memento memento = new Memento(vit,def);
        return memento;
    }

    //从备忘录状态恢复到GameRole
    public void recoverGameRoleFrom(Memento memento){
        this.vit=memento.getVit();
        this.def=memento.getDef();
    }

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

    public int getVit() {
        return vit;
    }

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

    public int getDef() {
        return def;
    }

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

//备份对象
public class Memento {

    private int vit;//攻击力
    private int def;//防御力

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

    public int getVit() {
        return vit;
    }

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

    public int getDef() {
        return def;
    }

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

//守护者对象  保存游戏角色状态
public class Caretaker {

    //如果只保存一次对象
    private Memento memento;
    //保存多次状态
//    private List<Memento> mementos;
//    //保存多个角色多种状态
//    private HashMap<String,List<Memento>> rolesMementos


    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}
public static void main(String[] args) {
    GameRole gameRole = new GameRole();
    gameRole.setVit(100);
    gameRole.setDef(100);
    System.out.println("-----大战前-----");
    gameRole.display();
    //保存备份
    Caretaker caretaker = new Caretaker();
    caretaker.setMemento(gameRole.createMemento());
    System.out.println("-----大战后-----");
    gameRole.setVit(90);
    gameRole.setDef(90);
    gameRole.display();

    System.out.println("-----恢复-----");
    gameRole.recoverGameRoleFrom(caretaker.getMemento());
    gameRole.display();

}

备忘录模式的注意事项和细节

  1. 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史 的状态

  2. 实现了信息的封装,使得用户不需要关心状态的保存细节

  3. 如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定 的内存, 这个需要注意

  4. 适用的应用场景:1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctri + z。 4、IE 中的后退。 4、数据库的事务管理

  5. 为了节约内存,备忘录模式可以和原型模式配合使用