前言
备忘录模式(Memento): 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
标准的备忘录模式有这么几种角色:
- Memonto:备忘录类,备份原始类中的信息
- Originator:原始类
- Caretaker:存储备忘录的类
备忘录模式是为了保存对象的内部状态,并在将来恢复,大多数软件提供的保存、打开,以及编辑过程中的Undo、Redo都是备忘录模式的应用。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public class Memento {
private String status;
public Memento(String status) { this.status = status; }
public String getStatus() { return status; }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
public class Originator {
private String status;
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public Memento saveToMemento() { return new Memento(status); }
public void restoreFromMemento(Memento memento) { status = memento.getStatus(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
public class Caretaker {
private final List<Memento> mementoList = new ArrayList<>();
public void addMemento(Memento memento) { mementoList.add(memento); }
public Memento getPrev() { return mementoList.get(mementoList.size() - 2); }
public Memento getCurrent() { return mementoList.get(mementoList.size() - 1); }
public List<Memento> getHistory() { return mementoList; }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| public class MementoTest {
public static void main(String[] args) { Caretaker caretaker = new Caretaker();
Originator originator = new Originator();
originator.setStatus("status1"); save(caretaker, originator);
originator.setStatus("status2"); save(caretaker, originator);
originator.setStatus("status3"); save(caretaker, originator);
originator.setStatus("status4"); save(caretaker, originator);
System.out.println("当前状态: " + originator.getStatus()); originator.restoreFromMemento(caretaker.getPrev()); save(caretaker, originator); System.out.println("撤销后,当前状态: " + originator.getStatus());
Originator originator1 = new Originator(); originator1.setStatus(caretaker.getCurrent().getStatus()); System.out.println("恢复后当前状态: " + originator1.getStatus());
System.out.println("===============操作历史================="); caretaker.getHistory().forEach(memento -> System.out.println("memento: " + memento.getStatus()));
}
private static void save(Caretaker caretaker, Originator originator) { Memento memento1 = originator.saveToMemento(); caretaker.addMemento(memento1); }
}
当前状态: status4 撤销后,当前状态: status3 恢复后当前状态: status3 ===============操作历史================= memento: status1 memento: status2 memento: status3 memento: status4 memento: status3
|
以上就实现了一个简单的备忘录,可以进行再一次封装,如加上每步的操作时间、地点、人物等, 或者指定恢复到某个进度
简单的对象,用一个String就可以表示其状态,对于复杂的对象模型,通常我们会使用JSON、XML等复杂格式