什么是备忘录模式

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

备忘录模式的结构

  • Originator(原发器)

  • Memento(备忘录)

  • MementoCaretaker(负责人)

一个实例

一个画图应用需要每次定位座标位置(Position).

实例代码

Position

public class Position {
    private int x;
    private int y;

    public Position(int x, int y){
        this.x = x;
        this.y = y;
    }

    public Memento save(){
        return new Memento(x,y);
    }

    public void restore(Memento m){
        this.x = m.getX();
        this.y = m.getY();
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String toString(){
        return "x:" + x + ",y:" + y;
    }

    class Memento {

        private int x;
        private int y;

        public Memento(int x,int y){
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }
    }

}

MementoCaretaker

import java.util.ArrayList;
import java.util.List;

public class MementoCaretaker {
    private List<Position.Memento> mementos = new ArrayList<Position.Memento>();

    public Position.Memento getMemento(int i) {
        return mementos.get(i);
    }

    public void setMemento(Position.Memento memento) {
        mementos.add(memento);
    }
}

Client

public class Client {
    private static MementoCaretaker caretaker = new MementoCaretaker();
    private static int index = -1;
    public static void main(String[] args){
        Position pos = new Position(1,2);
        draw(pos);
        pos.setX(3);
        draw(pos);
        undo(pos,index);
        redo(pos,index);
    }

    public static void draw(Position position){
        caretaker.setMemento(position.save());
        index++;
        System.out.println("draw! now(" + position + ")");
    }

    public static void undo(Position position,int i){
        position.restore(caretaker.getMemento(i-1));
        index--;
        System.out.println("undo! now(" + position + ")");
    }

    public static void redo(Position position,int i){
        position.restore(caretaker.getMemento(i+1));
        index++;
        System.out.println("redo! now(" + position + ")");
    }
}

实例结果

draw! now(x:1,y:2)
draw! now(x:3,y:2)
undo! now(x:1,y:2)
redo! now(x:3,y:2)

(完)