备忘录模式
备忘录模式是为了实现系统中的撤销操作而设计的,当用户操作失误需要撤销操作返回到某个历史状态时可以去除实现保存的历史状态来覆盖当前状态。
备忘录模式本身比较简单,在java网络应用中用的也比较少,因此加单介绍一下,并写了一个最简单的实例。
定义
在不破坏封装的前提下捕获一个对象的内部状态,并且在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
结构
- Originator原发器。需要被记录内部状态的类,它可以通过创建一个备忘录来保存当前的内部状态,也可以使用备忘录参数来覆盖自己的状态
- Memento备忘录。备忘录用于存储原发器的内步状态,针对原发器需要保存的状态而制定。需要注意的是,备忘录除了被原发器和负责人类使用之外,不能提供给其他类使用
- Caretaker负责人。负责保存备忘录,但不能对备忘录的内容进行操作或者检查。在此类中可以存储一个或者多个备忘录对象,他只负责存储对象,而不能修改对象,也不需要知道对象的内部实现。
实例
package memento;
public class Chess {
private int x;
private int y;
private String name;
public Chess(int x, int y, String name) {
super();
this.x = x;
this.y = y;
this.name = name;
}
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ChessMemento getMemento() {
return new ChessMemento(x, x, name);
}
public void setMemento(ChessMemento cm) {
this.x = cm.getX();
this.y = cm.getY();
this.name = cm.getName();
}
@Override
public String toString() {
return "Chess [x=" + x + ", y=" + y + ", name=" + name + "]";
}
}
package memento;
public class ChessMemento {
private int x;
private int y;
private String name;
public ChessMemento(int x, int y, String name) {
super();
this.x = x;
this.y = y;
this.name = name;
}
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package memento;
public class Recorder {
private ChessMemento chessMemento;
public ChessMemento getChessMemento() {
return chessMemento;
}
public void setChessMemento(ChessMemento chessMemento) {
this.chessMemento = chessMemento;
}
}
package memento;
public class Test {
public static void main(String[] args) {
Chess soldier = new Chess(1, 1, "兵");
System.out.println(soldier);
ChessMemento cm = soldier.getMemento();
Recorder r = new Recorder();
r.setChessMemento(cm);
soldier.setY(2);
System.out.println(soldier);
soldier.setMemento(r.getChessMemento());
System.out.println(soldier);
}
}
优缺点
- 通过提供备忘录类保持了对对象状态的隐藏,同时将对象的存储功能与撤销功能相分离,使得状态不会相互影响
- 通过集合可以实现多次撤销操作
- 缺点是针对每个需要记录的类都需要编写各自的备忘录类,并且编写记录和撤销的方法,工作量大,维护麻烦
适用场景
- 保护一个对象的内部状态,希望某些时刻能执行撤销操作
- 防止对象执行的过程中状态被破坏