备忘录模式
为什么引入备忘录模式
在我们的生活中,不可能一番风顺,也会犯错,但是如果可以向word那样,做错了就撤销,回到原来的样子,那就更棒了,又例如数据库,当数据库被破坏,我们通常的做法是从日志中找出原因,如果可以进行恢复,更好,如果不能恢复,我们会将以前备份的数据库迁移过来,然后从数据库日志中查看接下来要执行什么事务,来尽可能的恢复到原来的数据库,在这两种情况下,我们都需要回到事物原来的某个时刻的状态,这就需要备忘录模式。
备忘录模式是什么
再不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
核心思想
在目标类内部创建备份,有一个备份类用于记录目标类的状态,备份管理类则用于得到和设置备份类。
具体案例
时光倒流,遇到18岁的你,使用备忘录模式,
UML
代码
package com.dong.MementoM;
public class Human {
private String name;
private int age;
public Human(String name, int age) {
super();
this.name = name;
this.age = age;
}
//进行备份
public Memento saveTime() {
return new Memento(this.name,this.age);
}
//从备份中获取对象属性,进行赋值
public void TimeReturn(Memento p) {
this.name = p.getName();
this.age = p.getAge();
}
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;
}
@Override
public String toString() {
return "Human [name=" + name + ", age=" + age + "]";
}
}
package com.dong.MementoM;
public class Memento {
private String name;
private int age;
public Memento(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
package com.dong.MementoM;
public class MementoCareTaker {
private Memento memento ;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
package com.dong.MementoM;
/**
* Human [name=DL, age=17]
一年后
Human [name=DL, age=18]
两年后
Human [name=DL, age=20]
回到18岁
Human [name=DL, age=18]
* @author liuD
*/
public class client {
public static void main(String[] args) throws InterruptedException {
MementoCareTaker mct = new MementoCareTaker();
Human human = new Human("DL", 17);
System.out.println(human);
System.out.println("一年后");
Thread.sleep(1000);
human.setAge(18);
System.out.println(human);
mct.setMemento(human.saveTime());
System.out.println("两年后");
Thread.sleep(2000);
human.setAge(20);
System.out.println(human.toString());
System.out.println("回到18岁");
human.TimeReturn(mct.getMemento());
System.out.println(human.toString());
}
}
优点
从结构中可以看到类与类之间的低耦合,各司其职,管理明确,
扩展:
多备份备录模式:
在备忘录管理者类中使用HashMap记录目标的多个状态,
部分修改代码:
package com.dong.MementoM;
import java.util.HashMap;
public class MementoCareTaker {
private HashMap<String,Memento> memMap = new HashMap<String,Memento>();
public Memento getMemento(String id) {
return memMap.get(id);
}
public void setMemento(String id,Memento memento) {
memMap.put(id, memento);
}
}
package com.dong.MementoM;
/**
Human [name=DL, age=17]
一年后
Human [name=DL, age=18]
两年后
Human [name=DL, age=20]
回到18岁
Human [name=DL, age=18]
回到20岁
Human [name=DL, age=20]
* @author liuD
*/
public class client {
public static void main(String[] args) throws InterruptedException {
MementoCareTaker mct = new MementoCareTaker();
Human human = new Human("DL", 17);
System.out.println(human);
System.out.println("一年后");
Thread.sleep(1000);
human.setAge(18);
System.out.println(human);
mct.setMemento("001" ,human.saveTime());
System.out.println("两年后");
Thread.sleep(2000);
human.setAge(20);
mct.setMemento("002" ,human.saveTime());
System.out.println(human.toString());
System.out.println("回到18岁");
human.TimeReturn(mct.getMemento("001"));
System.out.println(human.toString());
System.out.println("回到20岁");
human.TimeReturn(mct.getMemento("002"));
System.out.println(human.toString());
}
}