1. 备忘录模式(Command Pattern)

1.1 介绍

  • 意图 :在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

  • 主要解决 :所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

  • 如何解决 :通过一个备忘录类专门存储对象状态。

  • 关键代码 :客户不与备忘录类耦合,与备忘录管理类耦合

1.2 优缺点

优点

  1. 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态

  2. 实现了信息的封装,使得用户不需要关心状态的保存细节

缺点

  1. 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

1.3 实现场景

  • 需要保存/恢复数据的相关状态场景。
  • 提供一个可回滚的操作

1.4 注意事项

  • 为了符合迪米特原则,还要增加一个管理备忘录的类

  • 为了节约内存,可使用原型模式+备忘录模式。

2. 案例实现

虽然说没有拿到宝藏,但是经历的这一切都是很有意义的,宝藏守卫拿出魔法相机,和我们合影以保存这一难忘时刻,当我们想起来答案时,对着照片大喊:“我是要成为海贼王的男人”,就可以直接传送到这里继续答题。

public class Me {
   
    private boolean smile = false;
    
    public void smile() {
   
        smile = true;
        System.out.println("我笑了");
    }
}
public class Friend {
   
}
public class Guard {
   
}
// 历史状态
public class State {
   
    private Me me;
    private Friend friend;
    private Guard guard;

    public State(Me me, Friend friend, Guard guard) {
   
        this.me = me;
        this.friend = friend;
        this.guard = guard;
    }
}

public class MagicCamera {
   
    private List<State> mementoList = new ArrayList<>();	// 历史记录
    
    public void add(State state){
   
        mementoList.add(state);
    }
    
    public State get(int index){
   
        return mementoList.get(index);
    }
}
public class Memento {
   
    public static void main(String[] args) {
   
        Me me = new Me();
        Friend friend = new Friend();
        Guard guard = new Guard();
        MagicCamera magicCamera = new MagicCamera();
        magicCamera.add(new State(me, friend, guard));	// 拍照
        me.smile();
        magicCamera.add(new State(me, friend, guard));
    }
}

3. 源码实现

  • 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
  • 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,idea等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。