备忘录模式

导读:本篇文章讲解 备忘录模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

备忘录模式

备忘录模式就是通过一个对象记录状态,实现保存和恢复的功能

1.备忘录模式的本质

备忘录模式的本质:保存和恢复内部状态。

备忘录模式的本质是在不破坏封装性的前提下,捕获和存储一个对象的内部状态,并在需要时将对象恢复到先前的状态。

该模式的核心目标是分离对象的状态保存和恢复的责任,使得对象本身不需要关心状态的存储和恢复过程。通过引入备忘录类作为中介,发起者对象可以将其状态保存到备忘录对象中,而不需要将其私有状态暴露给其他对象。

2.何时选用备忘录模式

建议在以下情况中选用备忘录模式。

  • 需要实现对象状态的撤销和恢复功能:当需要在对象中实现撤销操作或者恢复到先前状态的功能时,备忘录模式是一种有效的设计模式。它可以让对象保存其内部状态的快照,并在需要时进行恢复,从而实现撤销和恢复的功能。
  • 需要保存对象状态的历史记录:如果需要保存对象的状态历史记录,以便可以随时回溯到过去的状态,备忘录模式是一个合适的选择。通过使用备忘录模式,可以将对象的不同状态保存在备忘录中,并维护一个历史记录,以供需要时进行访问和恢复。
  • 需要在不破坏对象封装性的情况下保存和恢复对象状态:备忘录模式可以在不违反对象封装性的前提下,将对象的状态保存到备忘录对象中,并在需要时进行恢复。这样可以确保对象的私有状态不会被外部对象直接访问和修改。
  • 需要实现多级撤销功能:如果需要实现多级的撤销功能,即可以撤销多次操作,而不仅仅是一次,备忘录模式可以提供一种有效的实现方式。通过保存不同时间点的状态快照,可以在需要时一级一级地进行撤销操作,从而实现多级撤销功能。

3.优缺点

备忘录模式有以下优点。

  • 状态的封装和隔离:备忘录模式可以将对象的状态封装在备忘录对象中,使得对象的状态对外部对象是不可见的。这样可以确保对象的状态安全,同时也保护了对象的封装性。
  • 简化发起者对象:备忘录模式将状态的保存和恢复责任从发起者对象中分离出来,使得发起者对象的代码更加简洁和聚焦于自身的核心业务逻辑,而不需要关心状态的存储和恢复过程。
  • 实现撤销和恢复功能:备忘录模式为对象的撤销和恢复功能提供了一种简洁且可扩展的实现方式。对象可以通过保存不同时间点的状态快照,并在需要时进行恢复,实现撤销和恢复的功能。
  • 可扩展性:备忘录模式可以灵活地扩展,支持保存和恢复不同类型的对象状态。可以根据需要定义不同的备忘录类和发起者类,以适应不同对象的状态管理需求。

备忘录模式的缺点。

  • 内存消耗较大:备忘录模式需要为每个需要保存状态的对象创建备忘录对象,当对象状态较多或者对象数量较大时,可能会导致内存消耗较大。
  • 维护成本:如果需要维护大量的备忘录对象,可能会增加代码的复杂性和维护成本。在某些情况下,备忘录模式可能并不是最优的解决方案。

4.备忘录模式的结构

备忘录模式
  • 备忘录(Memento):存储发起者对象的内部状态。备忘录提供了获取状态和设置状态的接口,但只允许发起者访问。
  • 发起者(Originator):负责创建备忘录对象,将自身状态保存到备忘录中,并从备忘录中恢复状态。
  • 负责人(Caretaker):负责管理备忘录对象,即保存和提供备忘录对象给发起者使用。负责人对象并不直接访问备忘录的状态。

5.实现

以合同状态为例:

  • 草稿
  • 执行
  • 到期
备忘录模式

备忘一个状态

1.备忘录对象

@Data
@AllArgsConstructor
public class Memento {

    /**
     * 状态(可以是一个对象,也可以是一个属性)
     */
    private String state;

}

2.记录者

/**
 * @description:记录者
 */
@Data
public class Originator {

    /**
     * 状态
     */
    private String state;

    /**
     * 保存状态到备忘录对象中
     *
     * @return
     */
    public Memento createMemento() {
        return new Memento(state);
    }

    /**
     * 恢复备忘录中保存的状态
     *
     * @param memento
     */
    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }

}

3.备忘录管理者

/**
 * @description:备忘录管理者(负责人)
 */
public class Caretaker {

    private Memento memento;

    /**
     * 保存备忘录对象
     * @param memento
     */
    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    /**
     * 获取备忘录对象
     * @return
     */
    public Memento getMemento() {
        return this.memento;
    }
}

4.测试类

public class Client {

    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();
        // 设置初始状态
        originator.setState("草稿");
        System.out.println("初始状态: " + originator.getState());

        // 保存状态
        caretaker.setMemento(originator.createMemento());

        // 修改状态
        originator.setState("执行");
        System.out.println("修改后的状态: " + originator.getState());

        // 恢复状态
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("恢复后的状态: " + originator.getState());
    }
}

5.结果

初始状态: 草稿
修改后的状态: 执行
恢复后的状态: 草稿

备忘多个状态

1.备忘录对象和记录者代码不变

2.修改备忘录管理器代码

/**
 * @description:备忘录管理者
 */
public class Caretaker {

    /**
     * 备忘录可以存多个状态
     */
    private List<Memento> mementoList = new ArrayList<>();

    /**
     * 保存备忘录对象
     * @param memento
     */
    public void setMemento(Memento memento) {
        mementoList.add(memento);
    }

    /**
     * 索取备忘录对象
     * @return
     */
    public Memento getMemento() {
        Memento memento = null;
        if (mementoList.size() > 0) {
            memento = mementoList.get(mementoList.size() - 1);
            //恢复后移除这个状态
            mementoList.remove(mementoList.size() - 1);
        }
        return memento;
    }
}

3.测试类

public class Client {

    public static void main(String[] args) {
        com.cong.yanmo.behaviormodel.memo.manyState.Caretaker caretaker = new Caretaker();
        //创建原发器,设置状态
        Originator originator = new Originator();

        //管理者使用备忘录记录状态
        originator.setState("草稿");
        caretaker.setMemento(originator.createMemento());

        originator.setState("执行");
        caretaker.setMemento(originator.createMemento());

        //修改原发器的状态
        originator.setState("到期");
        System.out.println("当前合同状态:" + originator.getState());

        //恢复备忘录中存的状态
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("回退上一合同状态:" + originator.getState());

        originator.restoreMemento(caretaker.getMemento());
        System.out.println("回退上一合同状态:" + originator.getState());
    }
}

4.结果

当前合同状态:到期
回退上一合同状态:执行
回退上一合同状态:草稿

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15822.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!