备忘录模式——状态的记录与复用


Demo 地址: https://github.com/ooblee/HelloDesignPattern

1. 定义

备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。

其实就是状态的存储和复原

2. 设计

主要角色:

  • 原发器(Originator),可以把内部状态创建为备忘录,然后用备忘录来恢复内部状态。
  • 备忘录(Memento),存储原发器的状态,只供原发器和负责人使用。
  • 负责人(Caretaker),保存备忘录,但不能进行修改和检查。

类图如下:

备忘录模式-类图

简单的模型如下。

原发器 Originator,存在内部状态,并提供接口进行状态的保存和复原。

public class Originator {

    public int state;

    public Memento saveMemento() {
        Memento memento = new Memento();
        memento.setState(state);
        return memento;
    }

    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }

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

    public int getState() {
        return state;
    }
}

备忘录 Memento,对原发器需要存储和复原的状态进行保存。

public class Memento {

    private int state;

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

    public int getState() {
        return state;
    }
}

负责人 Caretaker,只做备忘录的存储。

public class Caretaker {

    private Memento memento;

    public Caretaker() {
    }

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

    public Memento getMemento() {
        return memento;
    }
}

客户端的调用,状态切换前都会保存一下之前的状态,在某个时间段用来复原。

public class TestMemento {

    public static void main(String[] args) {

        Caretaker caretaker = new Caretaker();
        Originator originator = new Originator();

        // 转移到状态 1
        originator.setState(1);
        System.out.println("state:" + originator.getState());

        // 转移到状态 2
        caretaker.setMemento(originator.saveMemento());
        originator.setState(2);
        System.out.println("state:" + originator.getState());

        // 转移到状态 3
        caretaker.setMemento(originator.saveMemento());
        originator.setState(3);
        System.out.println("state:" + originator.getState());

        // 回退到状态 2
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("state:" + originator.getState());

    }
}

2.1. 多次撤销

把负责人存储备忘录的数据结构调整一下,改成堆、栈、队列等。

2.2. 备忘录的封装

因为备忘录只允许原发器和负责人访问,不允许其他对象访问和修改,可以通过语言的一些特性实现。

Java 的一些方式:

  • 备忘录和原发器放同一个包,备忘录为包可见。
  • 备忘录直接作为原发器的内部类。

3. 应用

适用场景:

  • 需要保存状态并且进行回滚。实现单次撤销或者多次撤销操作。
  • 封装状态,防止外界破坏。

4. 特点

4.1. 优点

  • 可恢复,对状态恢复提供了一种实现机制。
  • 封装状态,原发器的状态被封装起来不会被外界修改到。

4.2. 缺点

  • 资源消耗,如果原发器需要存储和恢复的对象多且占用内存大,使用备忘录会增加系统内存消耗。
发布了61 篇原创文章 · 获赞 43 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/firefile/article/details/90314378
今日推荐