设计模式之备忘录模式

详细介绍

        备忘录模式(Memento Pattern)是一种行为设计模式,它为对象提供了一种恢复到之前状态的能力,而不会破坏对象的封装性。这种模式非常适合需要撤销操作或保存和恢复状态的场景,比如文本编辑器的撤销/重做功能、游戏中的存档/读档功能等。

核心组件:

  • Originator(发起人):负责创建、保存和恢复备忘录的类,维护自己的状态信息,并决定何时保存状态。
  • Memento(备忘录):用于存储发起人的内部状态,但不暴露这些状态的任何细节,保证了发起人的信息封装。
  • Caretaker(管理者/保姆):不直接访问备忘录的内容,仅负责保存和提供备忘录,避免了对发起人内部细节的了解。

使用场景

  1. 需要撤销操作:如文本编辑器的撤销功能,用户可以撤销到上一步或多步操作前的状态。
  2. 保存和恢复状态:游戏进度保存和读取,用户可以随时从保存点继续游戏。
  3. 状态恢复的复杂场景:当对象的状态复杂,且直接管理状态恢复逻辑成本较高时,备忘录模式提供了一个清晰的解决方案。

注意事项

  1. 状态封装:确保备忘录对象仅对发起人开放必要状态的访问权限,外部对象不能直接访问备忘录的内部状态,以保护发起人的封装性。
  2. 资源消耗:频繁创建和存储备忘录可能会占用大量内存,需要考虑资源管理策略,如限制保存的备忘录数量。
  3. 状态一致性:在恢复状态时,确保备忘录所保存的状态是一致的,避免不完整或损坏的状态被恢复。

优缺点

优点:

  • 简化状态恢复逻辑:通过备忘录模式,状态恢复逻辑集中在发起人内部,外部只需保存和传递备忘录对象。
  • 增强封装性:备忘录对象封装了发起人的内部状态,外部对象不需要了解这些细节。
  • 支持多级撤销:可以保存多个备忘录,支持多次撤销操作。

缺点:

  • 资源消耗:保存的状态越多,消耗的内存资源也越多。
  • 类的膨胀:增加了备忘录和发起人的类数量,增加了系统的复杂性。

Java代码示例

// 发起人
class Originator {
    private String state;

    public void setState(String state) {
        System.out.println("Originator: Setting state to " + state);
        this.state = state;
    }

    public String getState() {
        return state;
    }

    // 创建备忘录
    public Memento saveStateToMemento() {
        return new Memento(state);
    }

    // 从备忘录恢复状态
    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
        System.out.println("Originator: State set to " + state);
    }
}

// 备忘录
class Memento {
    private final String state;

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

    // 状态仅对发起人可见
    String getState() {
        return state;
    }
}

// 管理者
class Caretaker {
    private Memento memento;

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

    public Memento getMemento() {
        return memento;
    }
}

// 使用示例
public class MementoPatternDemo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setState("State #1");
        System.out.println("Originator: First state saved.\n");

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

        originator.setState("State #2");
        System.out.println("Originator: State changed to #2.\n");

        // 恢复状态
        originator.getStateFromMemento(caretaker.getMemento());
    }
}

使用过程中可能遇到的问题及解决方案

  1. 内存占用:如果状态数据量大,可以考虑实现备忘录的轻量级版本,仅保存关键状态或使用序列化技术将状态保存到磁盘上。
  2. 状态一致性问题:确保在保存状态到备忘录之前,发起人的状态是完整的、一致的。可以通过校验逻辑来确保状态的有效性。

与其他模式的对比

  • 与命令模式:两者都涉及到状态的恢复,但目的不同。命令模式主要用于实现撤销操作,侧重于动作的记录和执行;备忘录模式侧重于状态的保存和恢复。
  • 与状态模式:状态模式允许对象在内部状态改变时改变它的行为,而备忘录模式则是在外部保存对象的状态,以便将来恢复。状态模式改变的是行为,备忘录模式恢复的是状态。
  • 与访问者模式:访问者模式关注于对象结构上的元素访问和操作,而备忘录模式关注于状态的保存与恢复,两者关注点不同。

  • 31
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值