备忘录模式:
主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。做个图来分析一下:
Original类是原始类,里面有需要保存的属性value及创建一个备忘录类Mementor,用来保存value值。Memento类是备忘录类,Caretake类是存储备忘录的类(备忘录管理者),持有Memento类的实例,该模式很好理解。
角色分析:
Originator:对象,需要保存状态或者其他元素的元对象
Mementor:备忘录对象,负责记录
Caretake:守护备忘录对象,负责报错多个备忘录对象,使用集合或者map或者单个mementor,
实例代码一:
public class Original {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
//备份
public Mementor createMementor() {
return new Mementor(value);
}
//恢复备份的数据
public void restoreMemento(Mementor mementor) {
this.value = mementor.getValue();
}
}
***********************************************************************************
public class Mementor {
String value;
public Mementor(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
***********************************************************************************
/**
* 备份管理者
*/
public class Storage {
private Mementor mementor;
public Storage(Mementor mementor) {
this.mementor = mementor;
}
public Mementor getMementor() {
return mementor;
}
public void setMementor(Mementor mementor) {
this.mementor = mementor;
}
}
***********************************************************************************
/**
* 主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。
*
* Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值。
* Memento类是备忘录类,Storage类是存储备忘录的类,持有Memento类的实例,该模式很好理解。
*/
public class MainClass {
public static void main(String[] args) {
String value = "aaaaa";
Original original = new Original(value);
System.out.println("准备开始备份,最初的值:value="+value);
//备份数据到memetor中,存到storage中
Mementor mementor = original.createMementor();
Storage storage = new Storage(mementor);
System.out.println("已经备份完毕");
value= "bbbbbb";
System.out.println("修改原始值,修改后为value="+value);
System.out.println("开始恢复原始值");
original.restoreMemento(mementor);
System.out.println("恢复完毕,value="+original.getValue());
// 新建原始类时,value被初始化为aaaaa,后经过修改,将value的值置为bbbbbb,最后进行恢复状态,结果成功恢复了。其实我觉得这个模式叫“备份-恢复”模式最形象。
}
}
***********************************************************************************
测试结果
准备开始备份,最初的值:value=aaaaa
已经备份完毕
修改原始值,修改后为value=bbbbbb
开始恢复原始值
恢复完毕,value=aaaaa
实例代码二:
/**
* 原始类
*/
public class Person {
private String name;
private int age;
private String sex;
public Person() {
}
public Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
//创建备份
public Mementor creteMementor() {
return new Mementor(name,age,sex);
}
//还原
public void setMementor(Mementor mementor) {
this.age = mementor.getAge();
this.name = mementor.getName();
this.sex = mementor.getSex();
}
}
*************************************************************************
/**
* 备份者
*/
public class Mementor {
private String name;
private int age;
private String sex;
public Mementor(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public Mementor() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
*************************************************************************
/**
* 备份管理者
*/
public class CareTaker {
private Mementor mementor;
public Mementor getMementor() {
return mementor;
}
public void setMementor(Mementor mementor) {
this.mementor = mementor;
}
}
*************************************************************************
public class MainClass {
public static void main(String[] args) {
Person person = new Person("zhangsan",22,"男");
System.out.println("最初的:"+person);
/**
* 原始的方式备份
*/
//保存内部状态
Person backup = new Person();
backup.setName(person.getName());
backup.setAge(person.getAge());
backup.setSex(person.getSex());
System.out.println("备份的:"+backup);
//修改
person.setAge(20);
System.out.println("修改之后的:"+person);
//回滚还原
person.setAge(backup.getAge());
System.out.println("还原之后的: "+person);
System.out.println("*******************************");
/**
* 使用备忘录模式方式备份
*
*/
CareTaker careTaker = new CareTaker();
//备份
careTaker.setMementor(person.creteMementor());
System.out.println("最初的"+person);
person.setName("ibf");
person.setAge(11);
person.setSex("女");
System.out.println("修改后:"+person);
//还原
person.setMementor(careTaker.getMementor());
System.out.println("还原后的:"+person);
}
}
*************************************************************************
测试结果
最初的:Person{name='zhangsan', age=22, sex='男'}
备份的:Person{name='zhangsan', age=22, sex='男'}
修改之后的:Person{name='zhangsan', age=20, sex='男'}
还原之后的: Person{name='zhangsan', age=22, sex='男'}
*******************************
最初的Person{name='zhangsan', age=22, sex='男'}
修改后:Person{name='ibf', age=11, sex='女'}
还原后的:Person{name='zhangsan', age=22, sex='男'}
*************************************************************************
三、事例
原始对象Originator ,需要保存的是state属性
@Data
public class Originator {
private String state;
// 保存状态
public Mementor saveStateMementor() {
return new Mementor(state);
}
// 从备忘录中 恢复状态
public void getStateFromMementor(Mementor mementor) {
state = mementor.getState();
}
}
备忘录对象Mementor
@Data
public class Mementor {
private String state;
public Mementor(String state) {
this.state = state;
}
}
备忘录守护者Caretaker
public class Caretaker {
// 维护一个可以直接用Mementor对象
// 维护多个可以使用List<Mementor>
// 维护多维可以使用Map<String,ArrayList<Mementor>>
private List<Mementor> list = new ArrayList<>();
public void add(Mementor mementor) {
list.add(mementor);
}
public Mementor get(int index) {
return list.get(index);
}
}
客户端调用打印
public static void main(String[] args) {
// 备忘录模式
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
// 保存当前状态
originator.setState("状态#1 攻击力100");
caretaker.add(originator.saveStateMementor());
originator.setState("状态#2 攻击力80");
caretaker.add(originator.saveStateMementor());
originator.setState("状态#3 攻击力50");
caretaker.add(originator.saveStateMementor());
System.out.println("当前状态:" + originator.getState());
// 希望恢复的状态#1 从备忘录中恢复
originator.getStateFromMementor(caretaker.get(0));
System.out.println("恢复到#1 状态, 当前状态是" + originator.getState());
}
当前状态:状态#3 攻击力50
恢复到#1 状态, 当前状态是状态#1 攻击力100
四、事例
原始对象,需要保存vit和def两个属性
@Data
public class GameRole {
// 攻击力
private int vit;
// 防御力
private int def;
// 存储到备忘录中
public Mementor createMementor() {
return new Mementor(vit, def);
}
// 从备忘录恢复数据
public void receiveFromMementor(Mementor mementor) {
this.vit = mementor.getVit();
this.def = mementor.getDef();
}
public void display() {
System.out.println("游戏角色当前攻击力:" + this.vit + ";防御力:" + this.def);
}
}
备忘录对象
@Data
public class Mementor {
// 攻击力
private int vit;
// 防御力
private int def;
public Mementor(int vit, int def) {
this.vit = vit;
this.def = def;
}
}
备忘录守护者Caretake
@Data
public class Caretaker {
//private Map<String, List<Mementor>> listMap;
//private List<Mementor> list;
private Mementor mementor;
}
客户端调用打印
public static void main(String[] args) {
// 备忘录模式,配合原型模式一起使用
// 英雄大战
GameRole gameRole = new GameRole();
gameRole.setVit(100);
gameRole.setDef(100);
System.out.println("打boos之前的状态");
gameRole.display();
// 将当前状态保存备忘录
Mementor mementor = gameRole.createMementor();
System.out.println("与boos大战后的状态");
gameRole.setVit(30);
gameRole.setDef(30);
gameRole.display();
System.out.println("大战后,使用备忘录恢复巅峰战力");
gameRole.receiveFromMementor(mementor);
System.out.println("恢复战力后的状态");
gameRole.display();
}
打boos之前的状态
游戏角色当前攻击力:100;防御力:100
与boos大战后的状态
游戏角色当前攻击力:30;防御力:30
大战后,使用备忘录恢复巅峰战力
恢复战力后的状态
游戏角色当前攻击力:100;防御力:100