在不破坏封装性的前提下,捕获一个对象的状态,并在此对象的外部保存这个对象的状态,这样在以后就可以恢复到原先保存的状态。
Originator(发起人):它是需要保存的状态值的原始对象,状态值可以有多个也可以只有一个,它负责创建备忘录类并将需要保存的状态值保存在这个类中,它还可以恢复备忘录类中保存的状态值。
Memento(备忘录):负责保存状态值,和一个由状态值作为参数的构造器。
CareTaker(备忘录管理类):负责保存Memento。
Originator:
public class Originator {
private String state;//需要保存的状态值
/**
* 创建备忘录类,将需要保存的状态值保存在新建的Memo中
*/
public Memento createMeme(){
return new Memento(state);
}
/**
* 恢复备忘录
*/
public void setMeme(Memento meme){
this.state = meme.getState();
}
public void display(){
System.out.println("当前状态值:"+state);
}
public void setState(String state) {
this.state = state;
}
}
Memento:
public class Memento {
private String state;//需要保存的状态值
/**
* 保存状态值的构造器
*/
public Memento(String state){
this.state = state;
}
public String getState() {
return state;
}
}
CareTaker:
public class CareTaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
测试类:
public static void main(String[] args) {
Originator originator = new Originator();
originator.setState("on");
Memento createMeme = originator.createMeme();//创建备忘录类
CareTaker taker = new CareTaker();
taker.setMemento(createMeme);
originator.setState("off");//状态值发生改变
originator.display();
originator.setMeme(taker.getMemento());
originator.display();
}
结果:
相信很多人都玩过单机游戏,那么当我们打到boss的时候,如何在失败的情况下重新开始挑战boss呢,这里就用到存档,那么存档功能是如何实现的呢?
其实存档就可以用备忘录模式来实现:
游戏玩家:
public class GameRole {
//需要保存的状态值
private int HP;
private int attack;
private int defense;
//创建备忘录类
public RoleMemento createMemento(){
return new RoleMemento(HP,attack,defense);
}
//恢复备忘录类
public void setMemento(RoleMemento memento){
this.HP = memento.getHP();
this.attack = memento.getAttack();
this.defense = memento.getDefense();
}
public void display(){
System.out.println("角色当前状态:血量"+ HP +",攻击力"+ attack +",防御力"+defense);
}
public int getHP() {
return HP;
}
public void setHP(int hP) {
HP = hP;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
}
玩家备忘录:
public class RoleMemento {
//需要保存的状态值
private int HP;
private int attack;
private int defense;
public RoleMemento(int HP, int attack,int defense){
this.HP = HP;
this.attack = attack;
this.defense = defense;
}
public int getHP() {
return HP;
}
public int getAttack() {
return attack;
}
public int getDefense() {
return defense;
}
}
备忘录管理类:
public class RoleCareTaker {
private RoleMemento memento;
public RoleMemento getMemento() {
return memento;
}
public void setMemento(RoleMemento memento) {
this.memento = memento;
}
}
测试类:
public static void main(String[] args) {
GameRole gameRole = new GameRole();
gameRole.setHP(100);
gameRole.setAttack(100);
gameRole.setDefense(100);
//存档
RoleMemento memento = gameRole.createMemento();
//保存在备忘录管理类中
RoleCareTaker taker = new RoleCareTaker();
taker.setMemento(memento);
//和boss决斗失败
gameRole.setHP(0);
gameRole.setAttack(0);
gameRole.setDefense(0);
gameRole.display();
//恢复决斗前状态
gameRole.setMemento(taker.getMemento());
gameRole.display();
}
测试结果:
1.可以使对象恢复到某一时间节点的状态。
2.客户端无需考虑备忘录类的具体细节,实现信息的封装。
如果备忘录类越来越多,占用内存资源必定会对系统造成重大影响。
java.util.Date
Date date = new Date(100);构造器参数将会被缓存到一个long值中。
java.io.Serializable
比如说玩单机游戏有存档功能,该游戏的存档是将数据保存在硬盘中,那就用到Serializable接口,符合备忘录模式。