备忘录模式(Memento) 属于对象的行为模式。
备忘录模式是我觉得最容易理解的一种模式,它的名字取得非常的贴切。
1. 定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2. 使用的原因
想要恢复对象某时的原有状态
3. 适用的情况举例
有很多备忘录模式的应用,只是我们已经见过,却没细想这是备忘录模式的使用罢了,略略举几例:
eg1. 备忘录在jsp+javabean的使用:
在一系统中新增帐户时,在表单中需要填写用户名、密码、联系电话、地址等信息,如果有些字段没有填写或填写错误,当用户点击“提交”按钮时,需要在新增页面上保存用户输入的选项,并提示出错的选项。这就是利用JavaBean的scope="request"或scope="session"特性实现的,即是用备忘录模式实现的。
eg2. 修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。
eg3. 都说人生没有后悔药可买,我们都在为所做的事付出着代价,但在软世界里却有“后悔药”,我改变了某东西的某些状态之后,只要我们之前保存了该东西的某状态,我们就可以通过备忘录模式实现该东西的状态还原,其实这何尝不是一个能使时光倒流的“月光宝盒”,总“神奇”一词了得。
4. 类图结构及说明
1)类图如下所示:
2)类说明
i)Memento:备忘录角色, 主要负责的工作如下:
将发起人对象的内部状态存储起来;
可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。
ii)Originator:发起人角色,主要完成如下工作:
创建一个含有当前的内部状态的备忘录对象;
使用备忘录对象存储其内部状态。
iii)Caretaker:负责人角色,完成工作如下:
负责保存备忘录对象;
不保存备忘录对象的内容。
5. 使用举例
1)需求
Amigo的mother对Amigo当前的状态很不满意:不爱打扮,做事拖拖拉拉,十足马大哈。该mother想对Amigo进行改造,但又唯恐改造后还不如从前的Amigo好,有可能需要实现“时光倒流”功能。
2)分析
经过细细分析,这个状态保存功能其实可以通过备忘录模式来得到很好的实现,可通过备忘录来保存Amigo当前的状态:不爱打扮,做事拖拖拉拉,十足马大哈,以及其它的N多优点(哈哈哈。。。),如果改造后的Amigo不如从前,那我们让我们的“月光宝盒”来实现一下“时光倒流”,真神奇啊。。。
3)代码参考实现
i)发起人角色
public class Originator {
private String state;
/** *//**
* 工厂方法,返回一个新的备忘录对象
*/
public Memento createMemento {
return new Memento(state);
}
/** *//**
* 将发起人恢复到备忘录对象所记载的状态
*/
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
//省略状态state的getter和setter方法
}
ii)备忘录角色
public class Memento {
private String state;
/** *//**
* 构造函数
*/
public Memento(String state) {
this.state = state;
}
//省略state的getter和setter方法
}
iii)负责人角色
public class Caretaker {
private Memento memento;
/** *//**
* 备忘录的取值方法
*/
public Memento retrieveMemento {
return this.memento;
}
/** *//**
* 备忘录的保存方法
*/
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
iv)客户端模拟实现
public class Client {
private static Originator ori = new Originator();
private static Caretaker taker = new Caretaker();
public static void main(String[] args) {
//amigo当前的状态
ori.setState("不爱打扮,做事拖拖拉拉,十足马大哈");
//保存amigo当前的状态
taker.saveMemento(ori.createMemento());
//mother要对amigo进行改造
ori.setState("穿着时髦,做事精练");
//mother发现改造后产生了很多副作用,于是反悔了,要恢复女儿以前的样子
ori.restoreMemento(taker.retrieveMemento());
//amigo被打回原型,^_^
System.out.println("amigo当前情况: " + ori.getState());
}
}
mother真是滴,一棍子将我打回原型了。
无语也。。。