备忘录模式(Memento)

来源:互联网 发布:淘宝计划书范文 编辑:程序博客网 时间:2024/05/20 19:33

一、模式动机

在应用软件的开发过程中,有时我们有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现备份点和撤销机制,而要实现这些机制,我们必须事先将状态信息保存在某处,这样状态才能将对象恢复到它们原先的状态。

但是对象通常封装了其部分或所有的状态信息,使得其状态不能被其它对象访问,也就不可能在该对象之外保存其状态,而暴露其内部状态又将违反封装的原则,可能有损系统的可靠性和可扩展性。

二、模式定义

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

三、模式结构

备忘录模式

四、参与者

  • Originator:原发器
  • Memento:备忘录
  • Caretaker:负责人

五、示例代码

package design.pattern;class Originator {    private String state;    public String getState() {        return state;    }    public void setState(String state) {        this.state = state;    }    /**     * 恢复备忘录,将Memento导入并将相关数据恢复     *      * @param memento     */    public void setMemento(Memento memento) {        this.state = memento.getState();    }    /**     * 创建备忘录,将当前要保存的信息导入并实例化备忘录     *      * @return     */    public Memento createMemento() {        return new Memento(this.state);    }    /**     * 展示状态数据     */    public void show() {        System.out.println("当前状态是: " + state);    }}public class Memento {    private String state;    public String getState() {        return state;    }    public void setState(String state) {        this.state = state;    }    public Memento(String state) {        this.state = state;    }    public static void main(String[] args) {        Originator o = new Originator();        // 初始状态为On        o.setState("On");        o.show();        // 创建备忘录并保存状态        Caretaker caretaker = new Caretaker();        caretaker.setMemento(o.createMemento());        // 更改Originator状态=Off        o.setState("Off");        o.show();        // 恢复到原始状态        o.setMemento(caretaker.getMemento());        o.show();    }}class Caretaker {    private Memento memento;    public Memento getMemento() {        return memento;    }    public void setMemento(Memento memento) {        this.memento = memento;    }}
  • 优缺点

    • 备忘录模式的最大缺点就是资源消耗过大,如果类的成员变量太多,就不可避免占用大量的内存了,而且每保存一次对象的状态都需要消耗内存资源,如果知道这一点大家就容易理解为什么一些提供了Undo功能的软件在运行时需要的内存和硬盘空间比较大了。
  • 模式使用

    • 必须保存一个对象在某一个时刻的状态/部分状态,这样以后需要时它能够恢复到先前的状态。
    • 如果一个用接口来让其它对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
2 0