备忘录模式
类型:行为型
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。
适用场景:
- 保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。
- 防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。
角色
- 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
- 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
- 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
UML
包结构
memento(一个bean,存放状态)
package 备忘录模式.memento;
public class Record {
private int place;
public Record(int place){
this.place=place;
}
public int getPlace(){
return this.place;
}
}
careTaker(内置一个集合,用于存放许多历史记录(即前面那个bean)),负责对于记录的存取
package 备忘录模式.careTaker;
import 备忘录模式.memento.Record;
import java.util.ArrayList;
import java.util.List;
public class CareTaker {
private List<Record> recordList = new ArrayList<>();
public void saveRecord(Record record){
recordList.add(record);
}
public Record getRecord(int idx){
return recordList.get(idx);
}
}
originator(生成记录的类,同时具有回到某一个历史记录的能力)
package 备忘录模式.originator;
import 备忘录模式.memento.Record;
public class Player {
private int place;
public Record createRecord(){
return new Record(this.place);
}
public void restore(Record record){
this.place=record.getPlace();
}
public int getPlace() {
return this.place;
}
public void setPlace(int place) {
this.place = place;
}
}
客户端(我这里把他作为一场游戏的进行了)
package 备忘录模式.client;
import 备忘录模式.careTaker.CareTaker;
import 备忘录模式.originator.Player;
public class Game {
public static void main(String[] args) {
Player player = new Player();
CareTaker careTaker = new CareTaker();
//玩家走到1位置
player.setPlace(1);
careTaker.saveRecord(player.createRecord());
//玩家走到2位置
player.setPlace(2);
careTaker.saveRecord(player.createRecord());
//玩家走到3位置
player.setPlace(3);
careTaker.saveRecord(player.createRecord());
//当前玩家到达的位置
System.out.println("玩家到达了"+player.getPlace());
//玩家想回到第一次走到的位置
player.restore(careTaker.getRecord(0));
System.out.println("玩家回到了"+player.getPlace());
}
}
效果
玩家到达了3
玩家回到了1
Process finished with exit code 0
优点
- 备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。
- 备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。
缺点
- 资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。