设计模式 -- 备忘录模式

96 阅读2分钟

「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

含义: 捕获并且在外部保存一个内部状态,并且不破坏封装性。备忘录也是常见的备忘录,就是用来记录一些重要的东西,就比如一些游戏存档,当我们重新登录或者复活的时候,可以从保存的地方重新开始。

这里拿喝水做一个例子来讲解备忘录模式吧,首先在喝水前记录水的状态,当我喝完水的时候,仍然能够检测出之前水杯里有多少水。

1.简单记录水杯里的水

public class DrinkWater{
    
    private int milliliter;
    
    public int getMilliliter() {
        return milliliter;
    }
    public void setMilliliter(int milliliter) {
        this.milliliter = milliliter;
    }
    
    //状态显示
    public void stateDisplay() {
        System.out.println("水还有多少毫升:");
        System.out.println(this.milliliter);
        System.out.println("-----------------");
    }

    //水的初始状态
    public void getInitialState() {
        this.milliliter = 500;
    }

    //战斗后
    public void drink() {
        this.milliliter = 0;
    }

    //保存角色状态
    public WaterMemento saveState() {
        return (new WaterMemento(milliliter));
    }

    //记录我喝了多少水
    public void recovery(WaterMemento watermemento) {
        this.milliliter = watermemento.getMilliliter();
    }
}

2.备忘录类

public class WaterMemento {

    private int milliliter;  

    public WaterMemento(int milliliter) {
        this.milliliter = milliliter;
    }

    public int getMilliliter() {
        return milliliter;
    }

    public void setMilliliter(int milliliter) {
        this.milliliter = milliliter;
    }
}

3.备忘录管理类

public class WaterCaretaker {

    private WaterMemento memento;

    public WaterMemento getMemento() {
        return memento;
    }

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

4.测试

public class Client {

    public static void main(String[] args) {
        //喝水前
        DrinkWater drinkWater = new DrinkWater();
        drinkWater.getInitialState();
        drinkWater.stateDisplay();

        //保存水的进度
        WaterCaretaker caretaker = new WaterCaretaker();
        caretaker.setMemento(drinkWater.saveState());

        //喝水
        drinkWater.drink();
        drinkWater.stateDisplay();

        //查看喝的水
        drinkWater.recovery(caretaker.getMemento());
        drinkWater.stateDisplay();
    }

}

优点: 用户可以自由的恢复之前的状态,不会根据数据的改变影响已经记录下来的数据,并且信息仍然是满足封装的,并不需要了解内部的细节。

缺点: 成员多的话,每一次保存都要消耗一次资源,势必会影响系统性能。

使用场景: 1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

注意事项: 1、增加一个备忘录管理类以符合迪米特原则,还要使用原型模式+备忘录模式以节约内存。