什么是备忘录模式(Memento)?

120 阅读1分钟

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。

  1. 意图
    在不破坏对象封装的前提下,从内部记录对象的一个状态,并把这个状态保存到对象外部。
  2. 类图
    在这里插入图片描述
  3. 实例
/**
 * 改造后的备忘录模式,与原型模式结合,更具有实用性
 * 注意:通过这种方式恢复以后,返回的不再是原来对象,而是拷贝的快照对象
 */
class Memento<T> {
    private String state;
    private T t;

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

    public String getState() {
        return state;
    }

    public T getShortcut() {
        return t;
    }
}

class Originator implements Cloneable {
    private String state;
    private String name;

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

    public String getState() {
        return state;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Memento<Originator> saveToMemento () {
        try {
            Originator originator = (Originator) this.clone();
            return new Memento<>(state, originator);
        } catch (Exception e) {}
        return null;
    }

    public Originator recovery (Memento<Originator> memento) {
        return null != memento ? memento.getShortcut() : null;
    }
}

/**
 * 它的作用是记录和获取原状态
 */
class CareTaker<T> {
    private Map<String, Memento<T>> map = new HashMap<>();

    public void put (Memento<T> memento) {
        map.put(memento.getState(), memento);
    }

    public Memento<T> get(String state) {
        return map.get(state);
    }
}
  1. 测试
class MementoTest {
    public static void main(String[] args) {
        CareTaker<Originator> careTaker = new CareTaker<>();

        Originator originator = new Originator();
        originator.setState("abc");
        originator.setName("hello world");
        careTaker.put(originator.saveToMemento());

        originator.setState("bcd");
        originator.setName("kkk");
        careTaker.put(originator.saveToMemento());

        System.out.println(originator.recovery(careTaker.get("abc")).getName());
        System.out.println(originator.recovery(careTaker.get("bcd")).getName());
    }
}

运行结果:

hello world
kkk

想看更多吗?请访问:设计模式