1.概述
备忘录模式(Memento Pattern)是一种行为型模式,它的主要思想是在不破坏封装性的前提下,捕获一个对象的内部状态,并将该状态保存在该对象之外,这样以后就可将该对象恢复到原先保存的状态。它是相对简单的一种设计模式,能够允许用户取消不确定或者错误的操作,能够恢复到之前的状态。本文将详述备忘录模式的原理及使用方式。
2.原理及使用
2.1 原理
备忘录模式的UML类图如下所示:
备忘录模式主要包含三个核心角色:Originator(发起人)、Memento(备忘录)、Caretaker(管理者)。
Originator(发起人):负责创建一个备忘录对象,用来记录当前时刻的内部状态,并可使用备忘录恢复状态;
Memento(备忘录): 备忘录对象,负责保存好记录,即Originator内部状态;
Caretaker(管理者):守护者对象,负责保存多个备忘录对象。
2.2 案例
游戏角色有攻击力和防御力,在大战Boss前保存自身的攻击力和防御力,在于Boss大战时攻击力和防御力会下降,大战完成后攻击力恢复,要求从备忘录对象恢复到大战前的状态。根据案例,结合备忘录模式,得出类图如下:
编码如下:
public class Originator {
private Integer attack;
private Integer defence;
public Originator(Integer attack, Integer defence) {
this.attack = attack;
this.defence = defence;
}
public synchronized Memento createMemento() {
return new Memento(attack, defence);
}
public void recoveryFromMemento(Memento memento) {
this.attack = memento.getAttack();
this.defence = memento.getDefence();
}
public Integer getAttack() {
return attack;
}
public void setAttack(Integer attack) {
this.attack = attack;
}
public Integer getDefence() {
return defence;
}
public void setDefence(Integer defence) {
this.defence = defence;
}
public void display() {
System.out.println("当前人物攻击力为:" + getAttack() + ",当前任务防御力为:" + getDefence());
}
}
public class Memento {
private Integer attack;
private Integer defence;
public Memento(Integer attack, Integer defence) {
this.attack = attack;
this.defence = defence;
}
public Integer getAttack() {
return attack;
}
public void setAttack(Integer attack) {
this.attack = attack;
}
public Integer getDefence() {
return defence;
}
public void setDefence(Integer defence) {
this.defence = defence;
}
}
public class Caretake {
private HashMap<String, Memento> mementoHashMap = new HashMap<>();
public void add(String key, Memento memento) {
mementoHashMap.put(key, memento);
}
public Memento get(String key) {
return mementoHashMap.get(key);
}
}
public class Client {
public static void main(String[] args) {
//打boss前状态
Originator originator = new Originator(100, 100);
Caretake caretake = new Caretake();
caretake.add("beforeBoss", originator.createMemento());
System.out.print("攻击Boss前------");
originator.display();
//打boss后的状态
originator.setAttack(50);
originator.setDefence(30);
caretake.add("afterBoss",originator.createMemento());
System.out.print("攻击Boss后------");
originator.display();
//恢复打boss之前的状态
originator.recoveryFromMemento(caretake.get("beforeBoss"));
System.out.print("恢复后------");
originator.display();
}
}
运行结果如下:
2.3 备忘录模式的优缺点
2.3.1 优点
1.封装信息更加方便,使用者不需要知道封装的具体细节及实现;
2.便于信息的快速恢复,且能够方便地恢复到指定历史状态。
2.3.2 缺点
1.如果类状态信息较多,会占用大量内存,如果这样的实例过多,可能会导致内存溢出。
2.4 使用场景
包括游戏时存档、IE中的后退模式、数据库事务管理、Windows的回退功能。
3.小结
1.备忘录模式是一种快速恢复对象历史状态的一种模式,
2.为了节约内存,备忘录可以与原型模式结合使用。
4.参考文献
1.《设计模式之禅》-秦小波著
2.《大话设计模式》-程杰著
3.https://www.runoob.com/design-pattern/memento-pattern.html
4.https://www.bilibili.com/video/BV1G4411c7N4-尚硅谷设计模式