目录
一、简介
二、引入
三、掀开真面目
Memento模式也叫备忘录模式,是行为模式的一种。用于记录对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。
备忘录模式中最经典的案例是闯关游戏,比如当我们进行到第20关的时候,设置一下备份。当我们在第30关死亡时,就不需要重新回到第一关开始,可以选择保存的第20关的备份,继续从第20关开始了。
其实,在生活中也有许多相似的案例。如,我们个人的学籍卡,当我们进入大学时,会保存你的信息(姓名、出生年月、性别、专业等),当专业发生变化时,需要更新你的个人信息,但此时由于操作员失误,将同名的另一个人信息修改了,此时就需要将信息还原到以前正确的状态。按照这个思路,我们写出自己的代码。如下:
学生个人信息类
package com.sht.memento;
/**
* 学生个人信息
* @author SHT
*
*/
public class StudentInfo {
/**
* 姓名
*/
private String name;
/**
* 出生年月
*/
private String birthday;
/**
* 性别
*/
private String sex;
/**
* 专业
*/
private String profession;
public StudentInfo() {
}
public StudentInfo(String name, String birthday, String sex, String profession) {
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.profession = profession;
}
public void display() {
System.out.println("学生信息[姓名:"+name+",出生年月:"+birthday+",性别:"+sex+",专业:"+profession);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
}
测试类
package com.sht.memento;
/**
* 测试
* @author SHT
*
*/
public class TestDemo {
public static void main(String[] args) {
//入学时学生的个人信息
StudentInfo start = new StudentInfo("小明", "1992-10-8", "男", "信息管理");
System.out.println("------入学时信息---------");
start.display();
//备份学生的信息
StudentInfo backup = new StudentInfo();
backup.setName(start.getName());
backup.setBirthday(start.getBirthday());
backup.setSex(start.getSex());
backup.setProfession(start.getProfession());
//学生专业发生变化
start.setProfession("IT");
System.out.println("----中途改变专业后的信息----------");
start.display();
//发现改错了,需要还原
start.setName(backup.getName());
start.setBirthday(backup.getBirthday());
start.setSex(backup.getSex());
start.setProfession(backup.getProfession());
System.out.println("-----最终学生的个人信息----------");
start.display();
}
}
测试结果
------入学时信息---------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
----中途改变专业后的信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:IT
-----最终学生的个人信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
其实以上就是备忘录模式的思想。但在测试类(客户端)进行信息维护与还原,并不怎么专业,也没有充分发挥一个类只做一件事情的原则。所以,经过大神的重新设计,设计后的备忘录模式如下。
1.Originor类
可以理解为上面的学生信息类,需要被保存信息内部对象状态的类。
2.Memento类
保存Originor对象信息状态的类,与Originor类具有相同的属性。
3.CareTaker
管理Memento对象的类
下面就让我们改写上面的代码
StudentInfo类
package com.sht.memento;
/**
* 学生个人信息
* @author SHT
*
*/
public class StudentInfo {
/**
* 姓名
*/
private String name;
/**
* 出生年月
*/
private String birthday;
/**
* 性别
*/
private String sex;
/**
* 专业
*/
private String profession;
public StudentInfo() {
}
public StudentInfo(String name, String birthday, String sex, String profession) {
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.profession = profession;
}
public void display() {
System.out.println("学生信息[姓名:"+name+",出生年月:"+birthday+",性别:"+sex+",专业:"+profession);
}
//这里增加两个方法
//备份
public Memento createMemento() {
Memento m = new Memento(name,birthday,sex,profession);
return m;
}
//还原
public void setMemento(Memento m) {
this.name = m.getName();
this.birthday = m.getBirthday();
this.sex = m.getSex();
this.profession = m.getProfession();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
}
Memento类
package com.sht.memento;
public class Memento {
/**
* 姓名
*/
private String name;
/**
* 出生年月
*/
private String birthday;
/**
* 性别
*/
private String sex;
/**
* 专业
*/
private String profession;
public Memento() {
}
public Memento(String name, String birthday, String sex, String profession) {
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.profession = profession;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
}
CareTaker类
package com.sht.memento;
public class CareTaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
TestDemo类
package com.sht.memento;
/**
* 测试
* @author SHT
*
*/
public class TestDemo {
public static void main(String[] args) {
//入学时学生的个人信息
StudentInfo start = new StudentInfo("小明", "1992-10-8", "男", "信息管理");
System.out.println("------入学时信息---------");
start.display();
//备份学生的信息
CareTaker careTaker = new CareTaker();
careTaker.setMemento(start.createMemento());
//学生专业发生变化
start.setProfession("IT");
System.out.println("----中途改变专业后的信息----------");
start.display();
//发现改错了,需要还原
start.setMemento(careTaker.getMemento());
System.out.println("-----最终学生的个人信息----------");
start.display();
}
}
运行结果
------入学时信息---------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
----中途改变专业后的信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:IT
-----最终学生的个人信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
最后的结果是一样的。