备忘录模式包含如下角色:
Originator: 原发器
Memento: 备忘录
Caretaker: 负责人
后悔药人人都想要,但是事实却是残酷的,根本就没有后悔药可买,但是也不仅如此,在软件的世界里就有后悔药!备忘录模式就是一种后悔药,它给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态。
所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它实现了对信息的封装,使得客户不需要关心状态保存的细节。保存就要消耗资源,所以备忘录模式的缺点就在于消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
demo
入口类
package memento_method_mod;
import org.junit.Test;
/**
* 备忘录模式
* 备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。
*
* 介绍
* 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
*
* 主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
*
* 何时使用:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
*
* 如何解决:通过一个备忘录类专门存储对象状态。
*
* 关键代码:客户不与备忘录类耦合,与备忘录管理类耦合。
*
* 应用实例: 1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctrl + z。 4、IE 中的后退。 5、数据库的事务管理。
*
* 优点: 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 2、实现了信息的封装,使得用户不需要关心状态的保存细节。
*
* 缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
*
* 使用场景: 1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。
*
* 注意事项: 1、为了符合迪米特原则,还要增加一个管理备忘录的类。 2、为了节约内存,可使用原型模式+备忘录模式。
*/
public class Client {
@Test
public void test(){
Gamer gamer = new Gamer("1",10,"布藝頭盔");
CareTaker careTaker = new CareTaker();
careTaker.setBackup(gamer.backup());//第零次
System.out.println(gamer.toString());
gamer.setLife("10");
gamer.setLevel(2);
gamer.setEquipage("生鐵頭盔");
System.out.println(gamer.toString());
careTaker.setBackup(gamer.backup());//第一次
gamer.setLife("80");
gamer.setLevel(25);
gamer.setEquipage("粗鋼頭盔");
System.out.println(gamer.toString());
careTaker.setBackup(gamer.backup());//第二次
gamer.setLife("120");
gamer.setLevel(30);
gamer.setEquipage("黃金頭盔");
System.out.println(gamer.toString());
careTaker.setBackup(gamer.backup());//第三次
System.out.println(String.format("還原為第一次備份"));
gamer.recovery(careTaker.getBackupByIndex(1));
System.out.println(gamer.toString());
}
}
原发器 游戏角色
package memento_method_mod;
/**
* Originator: 原发器
* 游戏角色
*/
public class Gamer {
private String life;//生命值
private int level;//等级
private String equipage;//头盔
public Memento backup() {
Memento memento = new Memento(this.life,this.level,this.equipage);
return memento;
}
public Gamer(String life, int level, String equipage) {
this.life = life;
this.level = level;
this.equipage = equipage;
}
public void recovery(Memento memento) {
this.life = memento.getLife();
this.level = memento.getLevel();
this.equipage = memento.getEquipage();
}
@Override
public String toString() {
return "Gamer{" +
"life='" + life + '\'' +
", level=" + level +
", equipage='" + equipage + '\'' +
'}';
}
public String getLife() {
return life;
}
public void setLife(String life) {
this.life = life;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getEquipage() {
return equipage;
}
public void setEquipage(String equipage) {
this.equipage = equipage;
}
}
备忘录负责人
package memento_method_mod;
import java.util.ArrayList;
import java.util.List;
/**
* Caretaker: 负责人
*/
public class CareTaker {
List<Memento> mementoList = new ArrayList<>();
public void setBackup(Memento backup) {
mementoList.add(backup);
}
public Memento getBackupByIndex(int i) {
return mementoList.get(i);
}
}
备忘录
package memento_method_mod;
/**
* Memento: 备忘录
*/
public class Memento {
private String life;
private int level;
private String equipage;
public Memento(String life, int level, String equipage) {
this.life = life;
this.level = level;
this.equipage = equipage;
}
public String getLife() {
return life;
}
public void setLife(String life) {
this.life = life;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getEquipage() {
return equipage;
}
public void setEquipage(String equipage) {
this.equipage = equipage;
}
}
设计模式概览