备忘录模式浅谈

169 阅读2分钟

「这是我参与2022首次更文挑战的第38天,活动详情查看:2022首次更文挑战」。

一、什么是备忘录模式

不知道大家有没有经常使用ctrl+z和ctrl+y,进行撤销和恢复。或者偶尔会突然后悔,希望回到过去。正所谓棋如人生,人生如棋,落子无悔,我们能做到的只有把握现在。但在计算机世界,我们是可以有后悔药的,比如idea就可以撤销和恢复,还有如word,wps这些软件都有后悔药。备忘录模式:又叫快照模式,是指在不破坏对象封装性的情况下,捕捉到对象内部的状态,并将之保存起来,在需要的时候可以回滚到之前的状态。

二、备忘录模式的实现

public class ChineseChessMemento {
    private String state;

    public ChineseChessMemento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

象棋,备忘录角色,可以记录当前棋子的状态。

public class MyOperation {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        System.out.println(state);
        this.state = state;
    }

    public ChineseChessMemento createMemento() {
        return new ChineseChessMemento(state);
    }

    public void restoreMemento(ChineseChessMemento memento) {
        this.setState(memento.getState());
    }
}

发起人。此处指的是下棋的人,提供了创建备忘录和通过备忘录恢复状态的功能。

public class MementoManager {
    private List<ChineseChessMemento> mementoList = new ArrayList<>(2);

    public boolean add(ChineseChessMemento memento) {
        if (mementoList.size() > 2) {
            System.out.println("最多悔两步棋!");
            return false;
        } else {
            mementoList.add(memento);
            return true;
        }
    }

    public ChineseChessMemento getAndRemove() {
        if (mementoList.size() <= 0) {
            System.out.println("没有悔棋记录");
            return null;
        } else {
            ChineseChessMemento memento = mementoList.get(mementoList.size() - 1);
            mementoList.remove(memento);
            return memento;
        }
    }
}

备忘录的管理者,可以保存和获取备忘录。

public class MementoTest {
    public static void main(String[] args) {
        MementoManager mementoManager = new MementoManager();
        MyOperation operation= new MyOperation();
        System.out.println("我开始操作(我黑方)");
        operation.setState("operation:车出击");
        ChineseChessMemento memento1 = operation.createMemento();
        mementoManager.add(memento1);
        System.out.println("车吃掉了兵");
        System.out.println("红方出车");
        System.out.println("我继续操作");
        operation.setState("operation:马踩兵");
        ChineseChessMemento memento2 = operation.createMemento();
        mementoManager.add(memento2);
        System.out.println("车被红方的马吃掉了");
        System.out.println("我要不讲武德,悔棋");
        ChineseChessMemento memento3 = mementoManager.getAndRemove();
        operation.restoreMemento(memento3);
        ChineseChessMemento memento4 = mementoManager.getAndRemove();
        operation.restoreMemento(memento4);
    }
}

此处就是模拟下棋,我将之前走的步数存起来,然后回滚。 image.png

三、总结

优点:提供了一种简便的方式,可以简单的回顾到已经保存的状态。而且用户无需关心状态是如何保存的。

缺点:如果保存的状态过多,会消耗大量内存和资源。

备忘录模式的角色

  1. 发起人角色:提供创建备忘录和恢复备忘录的功能,记录当前时刻的内部信息。
  2. 备忘录角色:存储发起人的内部状态,发起人需要的时候提供給发起人。
  3. 管理者角色:提供备忘录角色的保存和获取,但自身不能对备忘录角色的内容进行修改和访问。